Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as select.


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

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • 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)
 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)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
comments: Optional[List[str]]
hashable_args: Any
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        )
this: Any
126    @property
127    def this(self) -> t.Any:
128        """
129        Retrieves the argument with key "this".
130        """
131        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

is_int: bool
175    @property
176    def is_int(self) -> bool:
177        """
178        Checks whether a Literal expression is an integer.
179        """
180        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
182    @property
183    def is_star(self) -> bool:
184        """Checks whether an expression is a star."""
185        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
196    @property
197    def alias_column_names(self) -> t.List[str]:
198        table_alias = self.args.get("alias")
199        if not table_alias:
200            return []
201        return [c.name for c in table_alias.args.get("columns") or []]
name: str
203    @property
204    def name(self) -> str:
205        return self.text("this")
alias_or_name: str
207    @property
208    def alias_or_name(self) -> str:
209        return self.alias or self.name
output_name: str
211    @property
212    def output_name(self) -> str:
213        """
214        Name of the output column if this expression is a selection.
215
216        If the Expression has no output name, an empty string is returned.
217
218        Example:
219            >>> from sqlglot import parse_one
220            >>> parse_one("SELECT a").expressions[0].output_name
221            'a'
222            >>> parse_one("SELECT b AS c").expressions[0].output_name
223            'c'
224            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
225            ''
226        """
227        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]
229    @property
230    def type(self) -> t.Optional[DataType]:
231        return self._type
def is_type(self, *dtypes) -> bool:
239    def is_type(self, *dtypes) -> bool:
240        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
242    def is_leaf(self) -> bool:
243        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
245    @property
246    def meta(self) -> t.Dict[str, t.Any]:
247        if self._meta is None:
248            self._meta = {}
249        return self._meta
def copy(self):
264    def copy(self):
265        """
266        Returns a deep copy of the expression.
267        """
268        new = deepcopy(self)
269        new.parent = self.parent
270        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
272    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
273        if self.comments is None:
274            self.comments = []
275        if comments:
276            for comment in comments:
277                _, *meta = comment.split(SQLGLOT_META)
278                if meta:
279                    for kv in "".join(meta).split(","):
280                        k, *v = kv.split("=")
281                        value = v[0].strip() if v else True
282                        self.meta[k.strip()] = value
283                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
285    def append(self, arg_key: str, value: t.Any) -> None:
286        """
287        Appends value to arg_key if it's a list or sets it as a new list.
288
289        Args:
290            arg_key (str): name of the list expression arg
291            value (Any): value to append to the list
292        """
293        if not isinstance(self.args.get(arg_key), list):
294            self.args[arg_key] = []
295        self.args[arg_key].append(value)
296        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:
298    def set(self, arg_key: str, value: t.Any) -> None:
299        """
300        Sets arg_key to value.
301
302        Args:
303            arg_key: name of the expression arg.
304            value: value to set the arg to.
305        """
306        if value is None:
307            self.args.pop(arg_key, None)
308            return
309
310        self.args[arg_key] = value
311        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
323    @property
324    def depth(self) -> int:
325        """
326        Returns the depth of this tree.
327        """
328        if self.parent:
329            return self.parent.depth + 1
330        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
332    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
333        """Yields the key and expression for all arguments, exploding list args."""
334        for k, vs in self.args.items():
335            if type(vs) is list:
336                for v in vs:
337                    if hasattr(v, "parent"):
338                        yield k, v
339            else:
340                if hasattr(vs, "parent"):
341                    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]:
343    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
344        """
345        Returns the first node in this tree which matches at least one of
346        the specified types.
347
348        Args:
349            expression_types: the expression type(s) to match.
350            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
351
352        Returns:
353            The node which matches the criteria or None if no such node was found.
354        """
355        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]:
357    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
358        """
359        Returns a generator object which visits all nodes in this tree and only
360        yields those that match at least one of the specified expression types.
361
362        Args:
363            expression_types: the expression type(s) to match.
364            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
365
366        Returns:
367            The generator object.
368        """
369        for expression, *_ in self.walk(bfs=bfs):
370            if isinstance(expression, expression_types):
371                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]:
373    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
374        """
375        Returns a nearest parent matching expression_types.
376
377        Args:
378            expression_types: the expression type(s) to match.
379
380        Returns:
381            The parent node.
382        """
383        ancestor = self.parent
384        while ancestor and not isinstance(ancestor, expression_types):
385            ancestor = ancestor.parent
386        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

parent_select: Optional[Select]
388    @property
389    def parent_select(self) -> t.Optional[Select]:
390        """
391        Returns the parent select statement.
392        """
393        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
395    @property
396    def same_parent(self) -> bool:
397        """Returns if the parent is the same class as itself."""
398        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
400    def root(self) -> Expression:
401        """
402        Returns the root expression of this tree.
403        """
404        expression = self
405        while expression.parent:
406            expression = expression.parent
407        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
409    def walk(self, bfs=True, prune=None):
410        """
411        Returns a generator object which visits all nodes in this tree.
412
413        Args:
414            bfs (bool): if set to True the BFS traversal order will be applied,
415                otherwise the DFS traversal will be used instead.
416            prune ((node, parent, arg_key) -> bool): callable that returns True if
417                the generator should stop traversing this branch of the tree.
418
419        Returns:
420            the generator object.
421        """
422        if bfs:
423            yield from self.bfs(prune=prune)
424        else:
425            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):
427    def dfs(self, parent=None, key=None, prune=None):
428        """
429        Returns a generator object which visits all nodes in this tree in
430        the DFS (Depth-first) order.
431
432        Returns:
433            The generator object.
434        """
435        parent = parent or self.parent
436        yield self, parent, key
437        if prune and prune(self, parent, key):
438            return
439
440        for k, v in self.iter_expressions():
441            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):
443    def bfs(self, prune=None):
444        """
445        Returns a generator object which visits all nodes in this tree in
446        the BFS (Breadth-first) order.
447
448        Returns:
449            The generator object.
450        """
451        queue = deque([(self, self.parent, None)])
452
453        while queue:
454            item, parent, key = queue.popleft()
455
456            yield item, parent, key
457            if prune and prune(item, parent, key):
458                continue
459
460            for k, v in item.iter_expressions():
461                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):
463    def unnest(self):
464        """
465        Returns the first non parenthesis child or self.
466        """
467        expression = self
468        while type(expression) is Paren:
469            expression = expression.this
470        return expression

Returns the first non parenthesis child or self.

def unalias(self):
472    def unalias(self):
473        """
474        Returns the inner expression if this is an Alias.
475        """
476        if isinstance(self, Alias):
477            return self.this
478        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
480    def unnest_operands(self):
481        """
482        Returns unnested operands as a tuple.
483        """
484        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
486    def flatten(self, unnest=True):
487        """
488        Returns a generator which yields child nodes whose parents are the same class.
489
490        A AND B AND C -> [A, B, C]
491        """
492        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and type(n) is not self.__class__):
493            if type(node) is not self.__class__:
494                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:
502    def to_s(self) -> str:
503        """
504        Same as __repr__, but includes additional information which can be useful
505        for debugging, like empty or missing args and the AST nodes' object IDs.
506        """
507        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:
509    def sql(self, dialect: DialectType = None, **opts) -> str:
510        """
511        Returns SQL string representation of this tree.
512
513        Args:
514            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
515            opts: other `sqlglot.generator.Generator` options.
516
517        Returns:
518            The SQL string.
519        """
520        from sqlglot.dialects import Dialect
521
522        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):
524    def transform(self, fun, *args, copy=True, **kwargs):
525        """
526        Recursively visits all tree nodes (excluding already transformed ones)
527        and applies the given transformation function to each node.
528
529        Args:
530            fun (function): a function which takes a node as an argument and returns a
531                new transformed node or the same node without modifications. If the function
532                returns None, then the corresponding node will be removed from the syntax tree.
533            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
534                modified in place.
535
536        Returns:
537            The transformed tree.
538        """
539        node = self.copy() if copy else self
540        new_node = fun(node, *args, **kwargs)
541
542        if new_node is None or not isinstance(new_node, Expression):
543            return new_node
544        if new_node is not node:
545            new_node.parent = node.parent
546            return new_node
547
548        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
549        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):
557    def replace(self, expression):
558        """
559        Swap out this expression with a new expression.
560
561        For example::
562
563            >>> tree = Select().select("x").from_("tbl")
564            >>> tree.find(Column).replace(column("y"))
565            Column(
566              this=Identifier(this=y, quoted=False))
567            >>> tree.sql()
568            'SELECT y FROM tbl'
569
570        Args:
571            expression: new node
572
573        Returns:
574            The new expression or expressions.
575        """
576        if not self.parent:
577            return expression
578
579        parent = self.parent
580        self.parent = None
581
582        replace_children(parent, lambda child: expression if child is self else child)
583        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:
585    def pop(self: E) -> E:
586        """
587        Remove this expression from its AST.
588
589        Returns:
590            The popped expression.
591        """
592        self.replace(None)
593        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
655    @classmethod
656    def load(cls, obj):
657        """
658        Load a dict (as returned by `Expression.dump`) into an Expression instance.
659        """
660        from sqlglot.serde import load
661
662        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:
664    def and_(
665        self,
666        *expressions: t.Optional[ExpOrStr],
667        dialect: DialectType = None,
668        copy: bool = True,
669        **opts,
670    ) -> Condition:
671        """
672        AND this condition with one or multiple expressions.
673
674        Example:
675            >>> condition("x=1").and_("y=1").sql()
676            'x = 1 AND y = 1'
677
678        Args:
679            *expressions: the SQL code strings to parse.
680                If an `Expression` instance is passed, it will be used as-is.
681            dialect: the dialect used to parse the input expression.
682            copy: whether to copy the involved expressions (only applies to Expressions).
683            opts: other options to use to parse the input expressions.
684
685        Returns:
686            The new And condition.
687        """
688        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1").and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
690    def or_(
691        self,
692        *expressions: t.Optional[ExpOrStr],
693        dialect: DialectType = None,
694        copy: bool = True,
695        **opts,
696    ) -> Condition:
697        """
698        OR this condition with one or multiple expressions.
699
700        Example:
701            >>> condition("x=1").or_("y=1").sql()
702            'x = 1 OR y = 1'
703
704        Args:
705            *expressions: the SQL code strings to parse.
706                If an `Expression` instance is passed, it will be used as-is.
707            dialect: the dialect used to parse the input expression.
708            copy: whether to copy the involved expressions (only applies to Expressions).
709            opts: other options to use to parse the input expressions.
710
711        Returns:
712            The new Or condition.
713        """
714        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1").or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
716    def not_(self, copy: bool = True):
717        """
718        Wrap this condition with NOT.
719
720        Example:
721            >>> condition("x=1").not_().sql()
722            'NOT x = 1'
723
724        Args:
725            copy: whether to copy this object.
726
727        Returns:
728            The new Not instance.
729        """
730        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
732    def as_(
733        self,
734        alias: str | Identifier,
735        quoted: t.Optional[bool] = None,
736        dialect: DialectType = None,
737        copy: bool = True,
738        **opts,
739    ) -> Alias:
740        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:
765    def isin(
766        self,
767        *expressions: t.Any,
768        query: t.Optional[ExpOrStr] = None,
769        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
770        copy: bool = True,
771        **opts,
772    ) -> In:
773        return In(
774            this=maybe_copy(self, copy),
775            expressions=[convert(e, copy=copy) for e in expressions],
776            query=maybe_parse(query, copy=copy, **opts) if query else None,
777            unnest=(
778                Unnest(
779                    expressions=[
780                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
781                        for e in ensure_list(unnest)
782                    ]
783                )
784                if unnest
785                else None
786            ),
787        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
789    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
790        return Between(
791            this=maybe_copy(self, copy),
792            low=convert(low, copy=copy, **opts),
793            high=convert(high, copy=copy, **opts),
794        )
def is_( self, other: Union[str, Expression]) -> Is:
796    def is_(self, other: ExpOrStr) -> Is:
797        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
799    def like(self, other: ExpOrStr) -> Like:
800        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
802    def ilike(self, other: ExpOrStr) -> ILike:
803        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
805    def eq(self, other: t.Any) -> EQ:
806        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
808    def neq(self, other: t.Any) -> NEQ:
809        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
811    def rlike(self, other: ExpOrStr) -> RegexpLike:
812        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
814    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
815        div = self._binop(Div, other)
816        div.args["typed"] = typed
817        div.args["safe"] = safe
818        return div
def desc(self, nulls_first: bool = False) -> Ordered:
820    def desc(self, nulls_first: bool = False) -> Ordered:
821        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):
904class Condition(Expression):
905    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
912class DerivedTable(Expression):
913    @property
914    def selects(self) -> t.List[Expression]:
915        return self.this.selects if isinstance(self.this, Query) else []
916
917    @property
918    def named_selects(self) -> t.List[str]:
919        return [select.output_name for select in self.selects]
selects: List[Expression]
913    @property
914    def selects(self) -> t.List[Expression]:
915        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
917    @property
918    def named_selects(self) -> t.List[str]:
919        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
 922class Query(Expression):
 923    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
 924        """
 925        Returns a `Subquery` that wraps around this query.
 926
 927        Example:
 928            >>> subquery = Select().select("x").from_("tbl").subquery()
 929            >>> Select().select("x").from_(subquery).sql()
 930            'SELECT x FROM (SELECT x FROM tbl)'
 931
 932        Args:
 933            alias: an optional alias for the subquery.
 934            copy: if `False`, modify this expression instance in-place.
 935        """
 936        instance = maybe_copy(self, copy)
 937        if not isinstance(alias, Expression):
 938            alias = TableAlias(this=to_identifier(alias)) if alias else None
 939
 940        return Subquery(this=instance, alias=alias)
 941
 942    def limit(
 943        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
 944    ) -> Select:
 945        """
 946        Adds a LIMIT clause to this query.
 947
 948        Example:
 949            >>> select("1").union(select("1")).limit(1).sql()
 950            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
 951
 952        Args:
 953            expression: the SQL code string to parse.
 954                This can also be an integer.
 955                If a `Limit` instance is passed, it will be used as-is.
 956                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
 957            dialect: the dialect used to parse the input expression.
 958            copy: if `False`, modify this expression instance in-place.
 959            opts: other options to use to parse the input expressions.
 960
 961        Returns:
 962            A limited Select expression.
 963        """
 964        return (
 965            select("*")
 966            .from_(self.subquery(alias="_l_0", copy=copy))
 967            .limit(expression, dialect=dialect, copy=False, **opts)
 968        )
 969
 970    @property
 971    def ctes(self) -> t.List[CTE]:
 972        """Returns a list of all the CTEs attached to this query."""
 973        with_ = self.args.get("with")
 974        return with_.expressions if with_ else []
 975
 976    @property
 977    def selects(self) -> t.List[Expression]:
 978        """Returns the query's projections."""
 979        raise NotImplementedError("Query objects must implement `selects`")
 980
 981    @property
 982    def named_selects(self) -> t.List[str]:
 983        """Returns the output names of the query's projections."""
 984        raise NotImplementedError("Query objects must implement `named_selects`")
 985
 986    def select(
 987        self,
 988        *expressions: t.Optional[ExpOrStr],
 989        append: bool = True,
 990        dialect: DialectType = None,
 991        copy: bool = True,
 992        **opts,
 993    ) -> Query:
 994        """
 995        Append to or set the SELECT expressions.
 996
 997        Example:
 998            >>> Select().select("x", "y").sql()
 999            'SELECT x, y'
1000
1001        Args:
1002            *expressions: the SQL code strings to parse.
1003                If an `Expression` instance is passed, it will be used as-is.
1004            append: if `True`, add to any existing expressions.
1005                Otherwise, this resets the expressions.
1006            dialect: the dialect used to parse the input expressions.
1007            copy: if `False`, modify this expression instance in-place.
1008            opts: other options to use to parse the input expressions.
1009
1010        Returns:
1011            The modified Query expression.
1012        """
1013        raise NotImplementedError("Query objects must implement `select`")
1014
1015    def with_(
1016        self,
1017        alias: ExpOrStr,
1018        as_: ExpOrStr,
1019        recursive: t.Optional[bool] = None,
1020        append: bool = True,
1021        dialect: DialectType = None,
1022        copy: bool = True,
1023        **opts,
1024    ) -> Query:
1025        """
1026        Append to or set the common table expressions.
1027
1028        Example:
1029            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1030            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1031
1032        Args:
1033            alias: the SQL code string to parse as the table name.
1034                If an `Expression` instance is passed, this is used as-is.
1035            as_: the SQL code string to parse as the table expression.
1036                If an `Expression` instance is passed, it will be used as-is.
1037            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1038            append: if `True`, add to any existing expressions.
1039                Otherwise, this resets the expressions.
1040            dialect: the dialect used to parse the input expression.
1041            copy: if `False`, modify this expression instance in-place.
1042            opts: other options to use to parse the input expressions.
1043
1044        Returns:
1045            The modified expression.
1046        """
1047        return _apply_cte_builder(
1048            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1049        )
1050
1051    def union(
1052        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1053    ) -> Union:
1054        """
1055        Builds a UNION expression.
1056
1057        Example:
1058            >>> import sqlglot
1059            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1060            'SELECT * FROM foo UNION SELECT * FROM bla'
1061
1062        Args:
1063            expression: the SQL code string.
1064                If an `Expression` instance is passed, it will be used as-is.
1065            distinct: set the DISTINCT flag if and only if this is true.
1066            dialect: the dialect used to parse the input expression.
1067            opts: other options to use to parse the input expressions.
1068
1069        Returns:
1070            The new Union expression.
1071        """
1072        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1073
1074    def intersect(
1075        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1076    ) -> Intersect:
1077        """
1078        Builds an INTERSECT expression.
1079
1080        Example:
1081            >>> import sqlglot
1082            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1083            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1084
1085        Args:
1086            expression: the SQL code string.
1087                If an `Expression` instance is passed, it will be used as-is.
1088            distinct: set the DISTINCT flag if and only if this is true.
1089            dialect: the dialect used to parse the input expression.
1090            opts: other options to use to parse the input expressions.
1091
1092        Returns:
1093            The new Intersect expression.
1094        """
1095        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1096
1097    def except_(
1098        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1099    ) -> Except:
1100        """
1101        Builds an EXCEPT expression.
1102
1103        Example:
1104            >>> import sqlglot
1105            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1106            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1107
1108        Args:
1109            expression: the SQL code string.
1110                If an `Expression` instance is passed, it will be used as-is.
1111            distinct: set the DISTINCT flag if and only if this is true.
1112            dialect: the dialect used to parse the input expression.
1113            opts: other options to use to parse the input expressions.
1114
1115        Returns:
1116            The new Except expression.
1117        """
1118        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
923    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
924        """
925        Returns a `Subquery` that wraps around this query.
926
927        Example:
928            >>> subquery = Select().select("x").from_("tbl").subquery()
929            >>> Select().select("x").from_(subquery).sql()
930            'SELECT x FROM (SELECT x FROM tbl)'
931
932        Args:
933            alias: an optional alias for the subquery.
934            copy: if `False`, modify this expression instance in-place.
935        """
936        instance = maybe_copy(self, copy)
937        if not isinstance(alias, Expression):
938            alias = TableAlias(this=to_identifier(alias)) if alias else None
939
940        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
942    def limit(
943        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
944    ) -> Select:
945        """
946        Adds a LIMIT clause to this query.
947
948        Example:
949            >>> select("1").union(select("1")).limit(1).sql()
950            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
951
952        Args:
953            expression: the SQL code string to parse.
954                This can also be an integer.
955                If a `Limit` instance is passed, it will be used as-is.
956                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
957            dialect: the dialect used to parse the input expression.
958            copy: if `False`, modify this expression instance in-place.
959            opts: other options to use to parse the input expressions.
960
961        Returns:
962            A limited Select expression.
963        """
964        return (
965            select("*")
966            .from_(self.subquery(alias="_l_0", copy=copy))
967            .limit(expression, dialect=dialect, copy=False, **opts)
968        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

ctes: List[CTE]
970    @property
971    def ctes(self) -> t.List[CTE]:
972        """Returns a list of all the CTEs attached to this query."""
973        with_ = self.args.get("with")
974        return with_.expressions if with_ else []

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

selects: List[Expression]
976    @property
977    def selects(self) -> t.List[Expression]:
978        """Returns the query's projections."""
979        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
981    @property
982    def named_selects(self) -> t.List[str]:
983        """Returns the output names of the query's projections."""
984        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

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) -> Query:
 986    def select(
 987        self,
 988        *expressions: t.Optional[ExpOrStr],
 989        append: bool = True,
 990        dialect: DialectType = None,
 991        copy: bool = True,
 992        **opts,
 993    ) -> Query:
 994        """
 995        Append to or set the SELECT expressions.
 996
 997        Example:
 998            >>> Select().select("x", "y").sql()
 999            'SELECT x, y'
1000
1001        Args:
1002            *expressions: the SQL code strings to parse.
1003                If an `Expression` instance is passed, it will be used as-is.
1004            append: if `True`, add to any existing expressions.
1005                Otherwise, this resets the expressions.
1006            dialect: the dialect used to parse the input expressions.
1007            copy: if `False`, modify this expression instance in-place.
1008            opts: other options to use to parse the input expressions.
1009
1010        Returns:
1011            The modified Query expression.
1012        """
1013        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def with_( self, 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) -> Query:
1015    def with_(
1016        self,
1017        alias: ExpOrStr,
1018        as_: ExpOrStr,
1019        recursive: t.Optional[bool] = None,
1020        append: bool = True,
1021        dialect: DialectType = None,
1022        copy: bool = True,
1023        **opts,
1024    ) -> Query:
1025        """
1026        Append to or set the common table expressions.
1027
1028        Example:
1029            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1030            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1031
1032        Args:
1033            alias: the SQL code string to parse as the table name.
1034                If an `Expression` instance is passed, this is used as-is.
1035            as_: the SQL code string to parse as the table expression.
1036                If an `Expression` instance is passed, it will be used as-is.
1037            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1038            append: if `True`, add to any existing expressions.
1039                Otherwise, this resets the expressions.
1040            dialect: the dialect used to parse the input expression.
1041            copy: if `False`, modify this expression instance in-place.
1042            opts: other options to use to parse the input expressions.
1043
1044        Returns:
1045            The modified expression.
1046        """
1047        return _apply_cte_builder(
1048            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1049        )

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1051    def union(
1052        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1053    ) -> Union:
1054        """
1055        Builds a UNION expression.
1056
1057        Example:
1058            >>> import sqlglot
1059            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1060            'SELECT * FROM foo UNION SELECT * FROM bla'
1061
1062        Args:
1063            expression: the SQL code string.
1064                If an `Expression` instance is passed, it will be used as-is.
1065            distinct: set the DISTINCT flag if and only if this is true.
1066            dialect: the dialect used to parse the input expression.
1067            opts: other options to use to parse the input expressions.
1068
1069        Returns:
1070            The new Union expression.
1071        """
1072        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1074    def intersect(
1075        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1076    ) -> Intersect:
1077        """
1078        Builds an INTERSECT expression.
1079
1080        Example:
1081            >>> import sqlglot
1082            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1083            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1084
1085        Args:
1086            expression: the SQL code string.
1087                If an `Expression` instance is passed, it will be used as-is.
1088            distinct: set the DISTINCT flag if and only if this is true.
1089            dialect: the dialect used to parse the input expression.
1090            opts: other options to use to parse the input expressions.
1091
1092        Returns:
1093            The new Intersect expression.
1094        """
1095        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1097    def except_(
1098        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1099    ) -> Except:
1100        """
1101        Builds an EXCEPT expression.
1102
1103        Example:
1104            >>> import sqlglot
1105            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1106            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1107
1108        Args:
1109            expression: the SQL code string.
1110                If an `Expression` instance is passed, it will be used as-is.
1111            distinct: set the DISTINCT flag if and only if this is true.
1112            dialect: the dialect used to parse the input expression.
1113            opts: other options to use to parse the input expressions.
1114
1115        Returns:
1116            The new Except expression.
1117        """
1118        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1121class UDTF(DerivedTable):
1122    @property
1123    def selects(self) -> t.List[Expression]:
1124        alias = self.args.get("alias")
1125        return alias.columns if alias else []
selects: List[Expression]
1122    @property
1123    def selects(self) -> t.List[Expression]:
1124        alias = self.args.get("alias")
1125        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1128class Cache(Expression):
1129    arg_types = {
1130        "this": True,
1131        "lazy": False,
1132        "options": False,
1133        "expression": False,
1134    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1137class Uncache(Expression):
1138    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1141class Refresh(Expression):
1142    pass
key = 'refresh'
class DDL(Expression):
1145class DDL(Expression):
1146    @property
1147    def ctes(self) -> t.List[CTE]:
1148        """Returns a list of all the CTEs attached to this statement."""
1149        with_ = self.args.get("with")
1150        return with_.expressions if with_ else []
1151
1152    @property
1153    def selects(self) -> t.List[Expression]:
1154        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1155        return self.expression.selects if isinstance(self.expression, Query) else []
1156
1157    @property
1158    def named_selects(self) -> t.List[str]:
1159        """
1160        If this statement contains a query (e.g. a CTAS), this returns the output
1161        names of the query's projections.
1162        """
1163        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1146    @property
1147    def ctes(self) -> t.List[CTE]:
1148        """Returns a list of all the CTEs attached to this statement."""
1149        with_ = self.args.get("with")
1150        return with_.expressions if with_ else []

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

selects: List[Expression]
1152    @property
1153    def selects(self) -> t.List[Expression]:
1154        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1155        return self.expression.selects if isinstance(self.expression, Query) else []

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

named_selects: List[str]
1157    @property
1158    def named_selects(self) -> t.List[str]:
1159        """
1160        If this statement contains a query (e.g. a CTAS), this returns the output
1161        names of the query's projections.
1162        """
1163        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

key = 'ddl'
class DML(Expression):
1166class DML(Expression):
1167    def returning(
1168        self,
1169        expression: ExpOrStr,
1170        dialect: DialectType = None,
1171        copy: bool = True,
1172        **opts,
1173    ) -> DML:
1174        """
1175        Set the RETURNING expression. Not supported by all dialects.
1176
1177        Example:
1178            >>> delete("tbl").returning("*", dialect="postgres").sql()
1179            'DELETE FROM tbl RETURNING *'
1180
1181        Args:
1182            expression: the SQL code strings to parse.
1183                If an `Expression` instance is passed, it will be used as-is.
1184            dialect: the dialect used to parse the input expressions.
1185            copy: if `False`, modify this expression instance in-place.
1186            opts: other options to use to parse the input expressions.
1187
1188        Returns:
1189            Delete: the modified expression.
1190        """
1191        return _apply_builder(
1192            expression=expression,
1193            instance=self,
1194            arg="returning",
1195            prefix="RETURNING",
1196            dialect=dialect,
1197            copy=copy,
1198            into=Returning,
1199            **opts,
1200        )
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:
1167    def returning(
1168        self,
1169        expression: ExpOrStr,
1170        dialect: DialectType = None,
1171        copy: bool = True,
1172        **opts,
1173    ) -> DML:
1174        """
1175        Set the RETURNING expression. Not supported by all dialects.
1176
1177        Example:
1178            >>> delete("tbl").returning("*", dialect="postgres").sql()
1179            'DELETE FROM tbl RETURNING *'
1180
1181        Args:
1182            expression: the SQL code strings to parse.
1183                If an `Expression` instance is passed, it will be used as-is.
1184            dialect: the dialect used to parse the input expressions.
1185            copy: if `False`, modify this expression instance in-place.
1186            opts: other options to use to parse the input expressions.
1187
1188        Returns:
1189            Delete: the modified expression.
1190        """
1191        return _apply_builder(
1192            expression=expression,
1193            instance=self,
1194            arg="returning",
1195            prefix="RETURNING",
1196            dialect=dialect,
1197            copy=copy,
1198            into=Returning,
1199            **opts,
1200        )

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):
1203class Create(DDL):
1204    arg_types = {
1205        "with": False,
1206        "this": True,
1207        "kind": True,
1208        "expression": False,
1209        "exists": False,
1210        "properties": False,
1211        "replace": False,
1212        "unique": False,
1213        "indexes": False,
1214        "no_schema_binding": False,
1215        "begin": False,
1216        "end": False,
1217        "clone": False,
1218    }
1219
1220    @property
1221    def kind(self) -> t.Optional[str]:
1222        kind = self.args.get("kind")
1223        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
kind: Optional[str]
1220    @property
1221    def kind(self) -> t.Optional[str]:
1222        kind = self.args.get("kind")
1223        return kind and kind.upper()
key = 'create'
class TruncateTable(Expression):
1226class TruncateTable(Expression):
1227    arg_types = {
1228        "expressions": True,
1229        "is_database": False,
1230        "exists": False,
1231        "only": False,
1232        "cluster": False,
1233        "identity": False,
1234        "option": False,
1235        "partition": False,
1236    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1242class Clone(Expression):
1243    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1246class Describe(Expression):
1247    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1250class Kill(Expression):
1251    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1254class Pragma(Expression):
1255    pass
key = 'pragma'
class Set(Expression):
1258class Set(Expression):
1259    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1262class Heredoc(Expression):
1263    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1266class SetItem(Expression):
1267    arg_types = {
1268        "this": False,
1269        "expressions": False,
1270        "kind": False,
1271        "collate": False,  # MySQL SET NAMES statement
1272        "global": False,
1273    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1276class Show(Expression):
1277    arg_types = {
1278        "this": True,
1279        "history": False,
1280        "terse": False,
1281        "target": False,
1282        "offset": False,
1283        "starts_with": False,
1284        "limit": False,
1285        "from": False,
1286        "like": False,
1287        "where": False,
1288        "db": False,
1289        "scope": False,
1290        "scope_kind": False,
1291        "full": False,
1292        "mutex": False,
1293        "query": False,
1294        "channel": False,
1295        "global": False,
1296        "log": False,
1297        "position": False,
1298        "types": False,
1299    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1302class UserDefinedFunction(Expression):
1303    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1306class CharacterSet(Expression):
1307    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1310class With(Expression):
1311    arg_types = {"expressions": True, "recursive": False}
1312
1313    @property
1314    def recursive(self) -> bool:
1315        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1313    @property
1314    def recursive(self) -> bool:
1315        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1318class WithinGroup(Expression):
1319    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1324class CTE(DerivedTable):
1325    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1328class TableAlias(Expression):
1329    arg_types = {"this": False, "columns": False}
1330
1331    @property
1332    def columns(self):
1333        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1331    @property
1332    def columns(self):
1333        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1336class BitString(Condition):
1337    pass
key = 'bitstring'
class HexString(Condition):
1340class HexString(Condition):
1341    pass
key = 'hexstring'
class ByteString(Condition):
1344class ByteString(Condition):
1345    pass
key = 'bytestring'
class RawString(Condition):
1348class RawString(Condition):
1349    pass
key = 'rawstring'
class UnicodeString(Condition):
1352class UnicodeString(Condition):
1353    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1356class Column(Condition):
1357    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1358
1359    @property
1360    def table(self) -> str:
1361        return self.text("table")
1362
1363    @property
1364    def db(self) -> str:
1365        return self.text("db")
1366
1367    @property
1368    def catalog(self) -> str:
1369        return self.text("catalog")
1370
1371    @property
1372    def output_name(self) -> str:
1373        return self.name
1374
1375    @property
1376    def parts(self) -> t.List[Identifier]:
1377        """Return the parts of a column in order catalog, db, table, name."""
1378        return [
1379            t.cast(Identifier, self.args[part])
1380            for part in ("catalog", "db", "table", "this")
1381            if self.args.get(part)
1382        ]
1383
1384    def to_dot(self) -> Dot | Identifier:
1385        """Converts the column into a dot expression."""
1386        parts = self.parts
1387        parent = self.parent
1388
1389        while parent:
1390            if isinstance(parent, Dot):
1391                parts.append(parent.expression)
1392            parent = parent.parent
1393
1394        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
1359    @property
1360    def table(self) -> str:
1361        return self.text("table")
db: str
1363    @property
1364    def db(self) -> str:
1365        return self.text("db")
catalog: str
1367    @property
1368    def catalog(self) -> str:
1369        return self.text("catalog")
output_name: str
1371    @property
1372    def output_name(self) -> str:
1373        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]
1375    @property
1376    def parts(self) -> t.List[Identifier]:
1377        """Return the parts of a column in order catalog, db, table, name."""
1378        return [
1379            t.cast(Identifier, self.args[part])
1380            for part in ("catalog", "db", "table", "this")
1381            if self.args.get(part)
1382        ]

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

def to_dot(self) -> Dot | Identifier:
1384    def to_dot(self) -> Dot | Identifier:
1385        """Converts the column into a dot expression."""
1386        parts = self.parts
1387        parent = self.parent
1388
1389        while parent:
1390            if isinstance(parent, Dot):
1391                parts.append(parent.expression)
1392            parent = parent.parent
1393
1394        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1397class ColumnPosition(Expression):
1398    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1401class ColumnDef(Expression):
1402    arg_types = {
1403        "this": True,
1404        "kind": False,
1405        "constraints": False,
1406        "exists": False,
1407        "position": False,
1408    }
1409
1410    @property
1411    def constraints(self) -> t.List[ColumnConstraint]:
1412        return self.args.get("constraints") or []
1413
1414    @property
1415    def kind(self) -> t.Optional[DataType]:
1416        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1410    @property
1411    def constraints(self) -> t.List[ColumnConstraint]:
1412        return self.args.get("constraints") or []
kind: Optional[DataType]
1414    @property
1415    def kind(self) -> t.Optional[DataType]:
1416        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1419class AlterColumn(Expression):
1420    arg_types = {
1421        "this": True,
1422        "dtype": False,
1423        "collate": False,
1424        "using": False,
1425        "default": False,
1426        "drop": False,
1427        "comment": False,
1428    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1431class RenameColumn(Expression):
1432    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1435class RenameTable(Expression):
1436    pass
key = 'renametable'
class SwapTable(Expression):
1439class SwapTable(Expression):
1440    pass
key = 'swaptable'
class Comment(Expression):
1443class Comment(Expression):
1444    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):
1447class Comprehension(Expression):
1448    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):
1452class MergeTreeTTLAction(Expression):
1453    arg_types = {
1454        "this": True,
1455        "delete": False,
1456        "recompress": False,
1457        "to_disk": False,
1458        "to_volume": False,
1459    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1463class MergeTreeTTL(Expression):
1464    arg_types = {
1465        "expressions": True,
1466        "where": False,
1467        "group": False,
1468        "aggregates": False,
1469    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1473class IndexConstraintOption(Expression):
1474    arg_types = {
1475        "key_block_size": False,
1476        "using": False,
1477        "parser": False,
1478        "comment": False,
1479        "visible": False,
1480        "engine_attr": False,
1481        "secondary_engine_attr": False,
1482    }
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):
1485class ColumnConstraint(Expression):
1486    arg_types = {"this": False, "kind": True}
1487
1488    @property
1489    def kind(self) -> ColumnConstraintKind:
1490        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1488    @property
1489    def kind(self) -> ColumnConstraintKind:
1490        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1493class ColumnConstraintKind(Expression):
1494    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1497class AutoIncrementColumnConstraint(ColumnConstraintKind):
1498    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1501class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1502    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1505class CaseSpecificColumnConstraint(ColumnConstraintKind):
1506    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1509class CharacterSetColumnConstraint(ColumnConstraintKind):
1510    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1513class CheckColumnConstraint(ColumnConstraintKind):
1514    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1517class ClusteredColumnConstraint(ColumnConstraintKind):
1518    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1521class CollateColumnConstraint(ColumnConstraintKind):
1522    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1525class CommentColumnConstraint(ColumnConstraintKind):
1526    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1529class CompressColumnConstraint(ColumnConstraintKind):
1530    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1533class DateFormatColumnConstraint(ColumnConstraintKind):
1534    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1537class DefaultColumnConstraint(ColumnConstraintKind):
1538    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1541class EncodeColumnConstraint(ColumnConstraintKind):
1542    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1545class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1546    # this: True -> ALWAYS, this: False -> BY DEFAULT
1547    arg_types = {
1548        "this": False,
1549        "expression": False,
1550        "on_null": False,
1551        "start": False,
1552        "increment": False,
1553        "minvalue": False,
1554        "maxvalue": False,
1555        "cycle": False,
1556    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1559class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1560    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1564class IndexColumnConstraint(ColumnConstraintKind):
1565    arg_types = {
1566        "this": False,
1567        "schema": True,
1568        "kind": False,
1569        "index_type": False,
1570        "options": False,
1571    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1574class InlineLengthColumnConstraint(ColumnConstraintKind):
1575    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1578class NonClusteredColumnConstraint(ColumnConstraintKind):
1579    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1582class NotForReplicationColumnConstraint(ColumnConstraintKind):
1583    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1586class NotNullColumnConstraint(ColumnConstraintKind):
1587    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1591class OnUpdateColumnConstraint(ColumnConstraintKind):
1592    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1596class TransformColumnConstraint(ColumnConstraintKind):
1597    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1600class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1601    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1604class TitleColumnConstraint(ColumnConstraintKind):
1605    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1608class UniqueColumnConstraint(ColumnConstraintKind):
1609    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1612class UppercaseColumnConstraint(ColumnConstraintKind):
1613    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1616class PathColumnConstraint(ColumnConstraintKind):
1617    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1622class ComputedColumnConstraint(ColumnConstraintKind):
1623    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1626class Constraint(Expression):
1627    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1630class Delete(DML):
1631    arg_types = {
1632        "with": False,
1633        "this": False,
1634        "using": False,
1635        "where": False,
1636        "returning": False,
1637        "limit": False,
1638        "tables": False,  # Multiple-Table Syntax (MySQL)
1639    }
1640
1641    def delete(
1642        self,
1643        table: ExpOrStr,
1644        dialect: DialectType = None,
1645        copy: bool = True,
1646        **opts,
1647    ) -> Delete:
1648        """
1649        Create a DELETE expression or replace the table on an existing DELETE expression.
1650
1651        Example:
1652            >>> delete("tbl").sql()
1653            'DELETE FROM tbl'
1654
1655        Args:
1656            table: the table from which to delete.
1657            dialect: the dialect used to parse the input expression.
1658            copy: if `False`, modify this expression instance in-place.
1659            opts: other options to use to parse the input expressions.
1660
1661        Returns:
1662            Delete: the modified expression.
1663        """
1664        return _apply_builder(
1665            expression=table,
1666            instance=self,
1667            arg="this",
1668            dialect=dialect,
1669            into=Table,
1670            copy=copy,
1671            **opts,
1672        )
1673
1674    def where(
1675        self,
1676        *expressions: t.Optional[ExpOrStr],
1677        append: bool = True,
1678        dialect: DialectType = None,
1679        copy: bool = True,
1680        **opts,
1681    ) -> Delete:
1682        """
1683        Append to or set the WHERE expressions.
1684
1685        Example:
1686            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1687            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1688
1689        Args:
1690            *expressions: the SQL code strings to parse.
1691                If an `Expression` instance is passed, it will be used as-is.
1692                Multiple expressions are combined with an AND operator.
1693            append: if `True`, AND the new expressions to any existing expression.
1694                Otherwise, this resets the expression.
1695            dialect: the dialect used to parse the input expressions.
1696            copy: if `False`, modify this expression instance in-place.
1697            opts: other options to use to parse the input expressions.
1698
1699        Returns:
1700            Delete: the modified expression.
1701        """
1702        return _apply_conjunction_builder(
1703            *expressions,
1704            instance=self,
1705            arg="where",
1706            append=append,
1707            into=Where,
1708            dialect=dialect,
1709            copy=copy,
1710            **opts,
1711        )
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:
1641    def delete(
1642        self,
1643        table: ExpOrStr,
1644        dialect: DialectType = None,
1645        copy: bool = True,
1646        **opts,
1647    ) -> Delete:
1648        """
1649        Create a DELETE expression or replace the table on an existing DELETE expression.
1650
1651        Example:
1652            >>> delete("tbl").sql()
1653            'DELETE FROM tbl'
1654
1655        Args:
1656            table: the table from which to delete.
1657            dialect: the dialect used to parse the input expression.
1658            copy: if `False`, modify this expression instance in-place.
1659            opts: other options to use to parse the input expressions.
1660
1661        Returns:
1662            Delete: the modified expression.
1663        """
1664        return _apply_builder(
1665            expression=table,
1666            instance=self,
1667            arg="this",
1668            dialect=dialect,
1669            into=Table,
1670            copy=copy,
1671            **opts,
1672        )

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:
1674    def where(
1675        self,
1676        *expressions: t.Optional[ExpOrStr],
1677        append: bool = True,
1678        dialect: DialectType = None,
1679        copy: bool = True,
1680        **opts,
1681    ) -> Delete:
1682        """
1683        Append to or set the WHERE expressions.
1684
1685        Example:
1686            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1687            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1688
1689        Args:
1690            *expressions: the SQL code strings to parse.
1691                If an `Expression` instance is passed, it will be used as-is.
1692                Multiple expressions are combined with an AND operator.
1693            append: if `True`, AND the new expressions to any existing expression.
1694                Otherwise, this resets the expression.
1695            dialect: the dialect used to parse the input expressions.
1696            copy: if `False`, modify this expression instance in-place.
1697            opts: other options to use to parse the input expressions.
1698
1699        Returns:
1700            Delete: the modified expression.
1701        """
1702        return _apply_conjunction_builder(
1703            *expressions,
1704            instance=self,
1705            arg="where",
1706            append=append,
1707            into=Where,
1708            dialect=dialect,
1709            copy=copy,
1710            **opts,
1711        )

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):
1714class Drop(Expression):
1715    arg_types = {
1716        "this": False,
1717        "kind": False,
1718        "exists": False,
1719        "temporary": False,
1720        "materialized": False,
1721        "cascade": False,
1722        "constraints": False,
1723        "purge": False,
1724    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1727class Filter(Expression):
1728    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1731class Check(Expression):
1732    pass
key = 'check'
class Connect(Expression):
1736class Connect(Expression):
1737    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1740class Prior(Expression):
1741    pass
key = 'prior'
class Directory(Expression):
1744class Directory(Expression):
1745    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1746    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1749class ForeignKey(Expression):
1750    arg_types = {
1751        "expressions": True,
1752        "reference": False,
1753        "delete": False,
1754        "update": False,
1755    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1758class ColumnPrefix(Expression):
1759    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1762class PrimaryKey(Expression):
1763    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1768class Into(Expression):
1769    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1772class From(Expression):
1773    @property
1774    def name(self) -> str:
1775        return self.this.name
1776
1777    @property
1778    def alias_or_name(self) -> str:
1779        return self.this.alias_or_name
name: str
1773    @property
1774    def name(self) -> str:
1775        return self.this.name
alias_or_name: str
1777    @property
1778    def alias_or_name(self) -> str:
1779        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1782class Having(Expression):
1783    pass
key = 'having'
class Hint(Expression):
1786class Hint(Expression):
1787    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1790class JoinHint(Expression):
1791    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1794class Identifier(Expression):
1795    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1796
1797    @property
1798    def quoted(self) -> bool:
1799        return bool(self.args.get("quoted"))
1800
1801    @property
1802    def hashable_args(self) -> t.Any:
1803        return (self.this, self.quoted)
1804
1805    @property
1806    def output_name(self) -> str:
1807        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1797    @property
1798    def quoted(self) -> bool:
1799        return bool(self.args.get("quoted"))
hashable_args: Any
1801    @property
1802    def hashable_args(self) -> t.Any:
1803        return (self.this, self.quoted)
output_name: str
1805    @property
1806    def output_name(self) -> str:
1807        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):
1811class Opclass(Expression):
1812    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1815class Index(Expression):
1816    arg_types = {
1817        "this": False,
1818        "table": False,
1819        "using": False,
1820        "where": False,
1821        "columns": False,
1822        "unique": False,
1823        "primary": False,
1824        "amp": False,  # teradata
1825        "include": False,
1826        "partition_by": False,  # teradata
1827    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'include': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1830class Insert(DDL, DML):
1831    arg_types = {
1832        "hint": False,
1833        "with": False,
1834        "this": True,
1835        "expression": False,
1836        "conflict": False,
1837        "returning": False,
1838        "overwrite": False,
1839        "exists": False,
1840        "partition": False,
1841        "alternative": False,
1842        "where": False,
1843        "ignore": False,
1844        "by_name": False,
1845    }
1846
1847    def with_(
1848        self,
1849        alias: ExpOrStr,
1850        as_: ExpOrStr,
1851        recursive: t.Optional[bool] = None,
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Insert:
1857        """
1858        Append to or set the common table expressions.
1859
1860        Example:
1861            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1862            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1863
1864        Args:
1865            alias: the SQL code string to parse as the table name.
1866                If an `Expression` instance is passed, this is used as-is.
1867            as_: the SQL code string to parse as the table expression.
1868                If an `Expression` instance is passed, it will be used as-is.
1869            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1870            append: if `True`, add to any existing expressions.
1871                Otherwise, this resets the expressions.
1872            dialect: the dialect used to parse the input expression.
1873            copy: if `False`, modify this expression instance in-place.
1874            opts: other options to use to parse the input expressions.
1875
1876        Returns:
1877            The modified expression.
1878        """
1879        return _apply_cte_builder(
1880            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1881        )
arg_types = {'hint': False, '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:
1847    def with_(
1848        self,
1849        alias: ExpOrStr,
1850        as_: ExpOrStr,
1851        recursive: t.Optional[bool] = None,
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Insert:
1857        """
1858        Append to or set the common table expressions.
1859
1860        Example:
1861            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1862            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1863
1864        Args:
1865            alias: the SQL code string to parse as the table name.
1866                If an `Expression` instance is passed, this is used as-is.
1867            as_: the SQL code string to parse as the table expression.
1868                If an `Expression` instance is passed, it will be used as-is.
1869            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1870            append: if `True`, add to any existing expressions.
1871                Otherwise, this resets the expressions.
1872            dialect: the dialect used to parse the input expression.
1873            copy: if `False`, modify this expression instance in-place.
1874            opts: other options to use to parse the input expressions.
1875
1876        Returns:
1877            The modified expression.
1878        """
1879        return _apply_cte_builder(
1880            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1881        )

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):
1884class OnConflict(Expression):
1885    arg_types = {
1886        "duplicate": False,
1887        "expressions": False,
1888        "action": False,
1889        "conflict_keys": False,
1890        "constraint": False,
1891    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1894class Returning(Expression):
1895    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1899class Introducer(Expression):
1900    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1904class National(Expression):
1905    pass
key = 'national'
class LoadData(Expression):
1908class LoadData(Expression):
1909    arg_types = {
1910        "this": True,
1911        "local": False,
1912        "overwrite": False,
1913        "inpath": True,
1914        "partition": False,
1915        "input_format": False,
1916        "serde": False,
1917    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1920class Partition(Expression):
1921    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
1924class PartitionRange(Expression):
1925    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
1928class Fetch(Expression):
1929    arg_types = {
1930        "direction": False,
1931        "count": False,
1932        "percent": False,
1933        "with_ties": False,
1934    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1937class Group(Expression):
1938    arg_types = {
1939        "expressions": False,
1940        "grouping_sets": False,
1941        "cube": False,
1942        "rollup": False,
1943        "totals": False,
1944        "all": False,
1945    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1948class Lambda(Expression):
1949    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1952class Limit(Expression):
1953    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
1956class Literal(Condition):
1957    arg_types = {"this": True, "is_string": True}
1958
1959    @property
1960    def hashable_args(self) -> t.Any:
1961        return (self.this, self.args.get("is_string"))
1962
1963    @classmethod
1964    def number(cls, number) -> Literal:
1965        return cls(this=str(number), is_string=False)
1966
1967    @classmethod
1968    def string(cls, string) -> Literal:
1969        return cls(this=str(string), is_string=True)
1970
1971    @property
1972    def output_name(self) -> str:
1973        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1959    @property
1960    def hashable_args(self) -> t.Any:
1961        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1963    @classmethod
1964    def number(cls, number) -> Literal:
1965        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1967    @classmethod
1968    def string(cls, string) -> Literal:
1969        return cls(this=str(string), is_string=True)
output_name: str
1971    @property
1972    def output_name(self) -> str:
1973        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):
1976class Join(Expression):
1977    arg_types = {
1978        "this": True,
1979        "on": False,
1980        "side": False,
1981        "kind": False,
1982        "using": False,
1983        "method": False,
1984        "global": False,
1985        "hint": False,
1986    }
1987
1988    @property
1989    def method(self) -> str:
1990        return self.text("method").upper()
1991
1992    @property
1993    def kind(self) -> str:
1994        return self.text("kind").upper()
1995
1996    @property
1997    def side(self) -> str:
1998        return self.text("side").upper()
1999
2000    @property
2001    def hint(self) -> str:
2002        return self.text("hint").upper()
2003
2004    @property
2005    def alias_or_name(self) -> str:
2006        return self.this.alias_or_name
2007
2008    def on(
2009        self,
2010        *expressions: t.Optional[ExpOrStr],
2011        append: bool = True,
2012        dialect: DialectType = None,
2013        copy: bool = True,
2014        **opts,
2015    ) -> Join:
2016        """
2017        Append to or set the ON expressions.
2018
2019        Example:
2020            >>> import sqlglot
2021            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2022            'JOIN x ON y = 1'
2023
2024        Args:
2025            *expressions: the SQL code strings to parse.
2026                If an `Expression` instance is passed, it will be used as-is.
2027                Multiple expressions are combined with an AND operator.
2028            append: if `True`, AND the new expressions to any existing expression.
2029                Otherwise, this resets the expression.
2030            dialect: the dialect used to parse the input expressions.
2031            copy: if `False`, modify this expression instance in-place.
2032            opts: other options to use to parse the input expressions.
2033
2034        Returns:
2035            The modified Join expression.
2036        """
2037        join = _apply_conjunction_builder(
2038            *expressions,
2039            instance=self,
2040            arg="on",
2041            append=append,
2042            dialect=dialect,
2043            copy=copy,
2044            **opts,
2045        )
2046
2047        if join.kind == "CROSS":
2048            join.set("kind", None)
2049
2050        return join
2051
2052    def using(
2053        self,
2054        *expressions: t.Optional[ExpOrStr],
2055        append: bool = True,
2056        dialect: DialectType = None,
2057        copy: bool = True,
2058        **opts,
2059    ) -> Join:
2060        """
2061        Append to or set the USING expressions.
2062
2063        Example:
2064            >>> import sqlglot
2065            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2066            'JOIN x USING (foo, bla)'
2067
2068        Args:
2069            *expressions: the SQL code strings to parse.
2070                If an `Expression` instance is passed, it will be used as-is.
2071            append: if `True`, concatenate the new expressions to the existing "using" list.
2072                Otherwise, this resets the expression.
2073            dialect: the dialect used to parse the input expressions.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            The modified Join expression.
2079        """
2080        join = _apply_list_builder(
2081            *expressions,
2082            instance=self,
2083            arg="using",
2084            append=append,
2085            dialect=dialect,
2086            copy=copy,
2087            **opts,
2088        )
2089
2090        if join.kind == "CROSS":
2091            join.set("kind", None)
2092
2093        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1988    @property
1989    def method(self) -> str:
1990        return self.text("method").upper()
kind: str
1992    @property
1993    def kind(self) -> str:
1994        return self.text("kind").upper()
side: str
1996    @property
1997    def side(self) -> str:
1998        return self.text("side").upper()
hint: str
2000    @property
2001    def hint(self) -> str:
2002        return self.text("hint").upper()
alias_or_name: str
2004    @property
2005    def alias_or_name(self) -> str:
2006        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:
2008    def on(
2009        self,
2010        *expressions: t.Optional[ExpOrStr],
2011        append: bool = True,
2012        dialect: DialectType = None,
2013        copy: bool = True,
2014        **opts,
2015    ) -> Join:
2016        """
2017        Append to or set the ON expressions.
2018
2019        Example:
2020            >>> import sqlglot
2021            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2022            'JOIN x ON y = 1'
2023
2024        Args:
2025            *expressions: the SQL code strings to parse.
2026                If an `Expression` instance is passed, it will be used as-is.
2027                Multiple expressions are combined with an AND operator.
2028            append: if `True`, AND the new expressions to any existing expression.
2029                Otherwise, this resets the expression.
2030            dialect: the dialect used to parse the input expressions.
2031            copy: if `False`, modify this expression instance in-place.
2032            opts: other options to use to parse the input expressions.
2033
2034        Returns:
2035            The modified Join expression.
2036        """
2037        join = _apply_conjunction_builder(
2038            *expressions,
2039            instance=self,
2040            arg="on",
2041            append=append,
2042            dialect=dialect,
2043            copy=copy,
2044            **opts,
2045        )
2046
2047        if join.kind == "CROSS":
2048            join.set("kind", None)
2049
2050        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:
2052    def using(
2053        self,
2054        *expressions: t.Optional[ExpOrStr],
2055        append: bool = True,
2056        dialect: DialectType = None,
2057        copy: bool = True,
2058        **opts,
2059    ) -> Join:
2060        """
2061        Append to or set the USING expressions.
2062
2063        Example:
2064            >>> import sqlglot
2065            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2066            'JOIN x USING (foo, bla)'
2067
2068        Args:
2069            *expressions: the SQL code strings to parse.
2070                If an `Expression` instance is passed, it will be used as-is.
2071            append: if `True`, concatenate the new expressions to the existing "using" list.
2072                Otherwise, this resets the expression.
2073            dialect: the dialect used to parse the input expressions.
2074            copy: if `False`, modify this expression instance in-place.
2075            opts: other options to use to parse the input expressions.
2076
2077        Returns:
2078            The modified Join expression.
2079        """
2080        join = _apply_list_builder(
2081            *expressions,
2082            instance=self,
2083            arg="using",
2084            append=append,
2085            dialect=dialect,
2086            copy=copy,
2087            **opts,
2088        )
2089
2090        if join.kind == "CROSS":
2091            join.set("kind", None)
2092
2093        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):
2096class Lateral(UDTF):
2097    arg_types = {
2098        "this": True,
2099        "view": False,
2100        "outer": False,
2101        "alias": False,
2102        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2103    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2106class MatchRecognize(Expression):
2107    arg_types = {
2108        "partition_by": False,
2109        "order": False,
2110        "measures": False,
2111        "rows": False,
2112        "after": False,
2113        "pattern": False,
2114        "define": False,
2115        "alias": False,
2116    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2121class Final(Expression):
2122    pass
key = 'final'
class Offset(Expression):
2125class Offset(Expression):
2126    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2129class Order(Expression):
2130    arg_types = {
2131        "this": False,
2132        "expressions": True,
2133        "interpolate": False,
2134        "siblings": False,
2135    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2139class WithFill(Expression):
2140    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2145class Cluster(Order):
2146    pass
key = 'cluster'
class Distribute(Order):
2149class Distribute(Order):
2150    pass
key = 'distribute'
class Sort(Order):
2153class Sort(Order):
2154    pass
key = 'sort'
class Ordered(Expression):
2157class Ordered(Expression):
2158    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):
2161class Property(Expression):
2162    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2165class AlgorithmProperty(Property):
2166    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2169class AutoIncrementProperty(Property):
2170    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2174class AutoRefreshProperty(Property):
2175    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2178class BlockCompressionProperty(Property):
2179    arg_types = {
2180        "autotemp": False,
2181        "always": False,
2182        "default": False,
2183        "manual": False,
2184        "never": False,
2185    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2188class CharacterSetProperty(Property):
2189    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2192class ChecksumProperty(Property):
2193    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2196class CollateProperty(Property):
2197    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2200class CopyGrantsProperty(Property):
2201    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2204class DataBlocksizeProperty(Property):
2205    arg_types = {
2206        "size": False,
2207        "units": False,
2208        "minimum": False,
2209        "maximum": False,
2210        "default": False,
2211    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2214class DefinerProperty(Property):
2215    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2218class DistKeyProperty(Property):
2219    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2222class DistStyleProperty(Property):
2223    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2226class EngineProperty(Property):
2227    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2230class HeapProperty(Property):
2231    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2234class ToTableProperty(Property):
2235    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2238class ExecuteAsProperty(Property):
2239    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2242class ExternalProperty(Property):
2243    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2246class FallbackProperty(Property):
2247    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2250class FileFormatProperty(Property):
2251    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2254class FreespaceProperty(Property):
2255    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InheritsProperty(Property):
2258class InheritsProperty(Property):
2259    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2262class InputModelProperty(Property):
2263    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2266class OutputModelProperty(Property):
2267    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2270class IsolatedLoadingProperty(Property):
2271    arg_types = {
2272        "no": False,
2273        "concurrent": False,
2274        "for_all": False,
2275        "for_insert": False,
2276        "for_none": False,
2277    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2280class JournalProperty(Property):
2281    arg_types = {
2282        "no": False,
2283        "dual": False,
2284        "before": False,
2285        "local": False,
2286        "after": False,
2287    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2290class LanguageProperty(Property):
2291    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2295class ClusteredByProperty(Property):
2296    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2299class DictProperty(Property):
2300    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2303class DictSubProperty(Property):
2304    pass
key = 'dictsubproperty'
class DictRange(Property):
2307class DictRange(Property):
2308    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2313class OnCluster(Property):
2314    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2317class LikeProperty(Property):
2318    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2321class LocationProperty(Property):
2322    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2325class LockProperty(Property):
2326    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2329class LockingProperty(Property):
2330    arg_types = {
2331        "this": False,
2332        "kind": True,
2333        "for_or_in": False,
2334        "lock_type": True,
2335        "override": False,
2336    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2339class LogProperty(Property):
2340    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2343class MaterializedProperty(Property):
2344    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2347class MergeBlockRatioProperty(Property):
2348    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):
2351class NoPrimaryIndexProperty(Property):
2352    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2355class OnProperty(Property):
2356    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2359class OnCommitProperty(Property):
2360    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2363class PartitionedByProperty(Property):
2364    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2368class PartitionBoundSpec(Expression):
2369    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2370    arg_types = {
2371        "this": False,
2372        "expression": False,
2373        "from_expressions": False,
2374        "to_expressions": False,
2375    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2378class PartitionedOfProperty(Property):
2379    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2380    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2383class RemoteWithConnectionModelProperty(Property):
2384    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2387class ReturnsProperty(Property):
2388    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2391class RowFormatProperty(Property):
2392    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2395class RowFormatDelimitedProperty(Property):
2396    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2397    arg_types = {
2398        "fields": False,
2399        "escaped": False,
2400        "collection_items": False,
2401        "map_keys": False,
2402        "lines": False,
2403        "null": False,
2404        "serde": False,
2405    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2408class RowFormatSerdeProperty(Property):
2409    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2413class QueryTransform(Expression):
2414    arg_types = {
2415        "expressions": True,
2416        "command_script": True,
2417        "schema": False,
2418        "row_format_before": False,
2419        "record_writer": False,
2420        "row_format_after": False,
2421        "record_reader": False,
2422    }
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):
2425class SampleProperty(Property):
2426    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2429class SchemaCommentProperty(Property):
2430    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2433class SerdeProperties(Property):
2434    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2437class SetProperty(Property):
2438    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SetConfigProperty(Property):
2441class SetConfigProperty(Property):
2442    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2445class SettingsProperty(Property):
2446    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2449class SortKeyProperty(Property):
2450    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2453class SqlReadWriteProperty(Property):
2454    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2457class SqlSecurityProperty(Property):
2458    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2461class StabilityProperty(Property):
2462    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2465class TemporaryProperty(Property):
2466    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2469class TransformModelProperty(Property):
2470    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2473class TransientProperty(Property):
2474    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2477class VolatileProperty(Property):
2478    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2481class WithDataProperty(Property):
2482    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2485class WithJournalTableProperty(Property):
2486    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2489class WithSystemVersioningProperty(Property):
2490    # this -> history table name, expression -> data consistency check
2491    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2494class Properties(Expression):
2495    arg_types = {"expressions": True}
2496
2497    NAME_TO_PROPERTY = {
2498        "ALGORITHM": AlgorithmProperty,
2499        "AUTO_INCREMENT": AutoIncrementProperty,
2500        "CHARACTER SET": CharacterSetProperty,
2501        "CLUSTERED_BY": ClusteredByProperty,
2502        "COLLATE": CollateProperty,
2503        "COMMENT": SchemaCommentProperty,
2504        "DEFINER": DefinerProperty,
2505        "DISTKEY": DistKeyProperty,
2506        "DISTSTYLE": DistStyleProperty,
2507        "ENGINE": EngineProperty,
2508        "EXECUTE AS": ExecuteAsProperty,
2509        "FORMAT": FileFormatProperty,
2510        "LANGUAGE": LanguageProperty,
2511        "LOCATION": LocationProperty,
2512        "LOCK": LockProperty,
2513        "PARTITIONED_BY": PartitionedByProperty,
2514        "RETURNS": ReturnsProperty,
2515        "ROW_FORMAT": RowFormatProperty,
2516        "SORTKEY": SortKeyProperty,
2517    }
2518
2519    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2520
2521    # CREATE property locations
2522    # Form: schema specified
2523    #   create [POST_CREATE]
2524    #     table a [POST_NAME]
2525    #     (b int) [POST_SCHEMA]
2526    #     with ([POST_WITH])
2527    #     index (b) [POST_INDEX]
2528    #
2529    # Form: alias selection
2530    #   create [POST_CREATE]
2531    #     table a [POST_NAME]
2532    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2533    #     index (c) [POST_INDEX]
2534    class Location(AutoName):
2535        POST_CREATE = auto()
2536        POST_NAME = auto()
2537        POST_SCHEMA = auto()
2538        POST_WITH = auto()
2539        POST_ALIAS = auto()
2540        POST_EXPRESSION = auto()
2541        POST_INDEX = auto()
2542        UNSUPPORTED = auto()
2543
2544    @classmethod
2545    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2546        expressions = []
2547        for key, value in properties_dict.items():
2548            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2549            if property_cls:
2550                expressions.append(property_cls(this=convert(value)))
2551            else:
2552                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2553
2554        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>}
PROPERTY_TO_NAME = {<class 'AlgorithmProperty'>: 'ALGORITHM', <class 'AutoIncrementProperty'>: 'AUTO_INCREMENT', <class 'CharacterSetProperty'>: 'CHARACTER SET', <class 'ClusteredByProperty'>: 'CLUSTERED_BY', <class 'CollateProperty'>: 'COLLATE', <class 'SchemaCommentProperty'>: 'COMMENT', <class 'DefinerProperty'>: 'DEFINER', <class 'DistKeyProperty'>: 'DISTKEY', <class 'DistStyleProperty'>: 'DISTSTYLE', <class 'EngineProperty'>: 'ENGINE', <class 'ExecuteAsProperty'>: 'EXECUTE AS', <class 'FileFormatProperty'>: 'FORMAT', <class 'LanguageProperty'>: 'LANGUAGE', <class 'LocationProperty'>: 'LOCATION', <class 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2544    @classmethod
2545    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2546        expressions = []
2547        for key, value in properties_dict.items():
2548            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2549            if property_cls:
2550                expressions.append(property_cls(this=convert(value)))
2551            else:
2552                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2553
2554        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2534    class Location(AutoName):
2535        POST_CREATE = auto()
2536        POST_NAME = auto()
2537        POST_SCHEMA = auto()
2538        POST_WITH = auto()
2539        POST_ALIAS = auto()
2540        POST_EXPRESSION = auto()
2541        POST_INDEX = auto()
2542        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):
2557class Qualify(Expression):
2558    pass
key = 'qualify'
class InputOutputFormat(Expression):
2561class InputOutputFormat(Expression):
2562    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2566class Return(Expression):
2567    pass
key = 'return'
class Reference(Expression):
2570class Reference(Expression):
2571    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2574class Tuple(Expression):
2575    arg_types = {"expressions": False}
2576
2577    def isin(
2578        self,
2579        *expressions: t.Any,
2580        query: t.Optional[ExpOrStr] = None,
2581        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2582        copy: bool = True,
2583        **opts,
2584    ) -> In:
2585        return In(
2586            this=maybe_copy(self, copy),
2587            expressions=[convert(e, copy=copy) for e in expressions],
2588            query=maybe_parse(query, copy=copy, **opts) if query else None,
2589            unnest=(
2590                Unnest(
2591                    expressions=[
2592                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2593                        for e in ensure_list(unnest)
2594                    ]
2595                )
2596                if unnest
2597                else None
2598            ),
2599        )
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:
2577    def isin(
2578        self,
2579        *expressions: t.Any,
2580        query: t.Optional[ExpOrStr] = None,
2581        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2582        copy: bool = True,
2583        **opts,
2584    ) -> In:
2585        return In(
2586            this=maybe_copy(self, copy),
2587            expressions=[convert(e, copy=copy) for e in expressions],
2588            query=maybe_parse(query, copy=copy, **opts) if query else None,
2589            unnest=(
2590                Unnest(
2591                    expressions=[
2592                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2593                        for e in ensure_list(unnest)
2594                    ]
2595                )
2596                if unnest
2597                else None
2598            ),
2599        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
class QueryOption(Expression):
2630class QueryOption(Expression):
2631    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2635class WithTableHint(Expression):
2636    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2640class IndexTableHint(Expression):
2641    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2645class HistoricalData(Expression):
2646    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2649class Table(Expression):
2650    arg_types = {
2651        "this": False,
2652        "alias": False,
2653        "db": False,
2654        "catalog": False,
2655        "laterals": False,
2656        "joins": False,
2657        "pivots": False,
2658        "hints": False,
2659        "system_time": False,
2660        "version": False,
2661        "format": False,
2662        "pattern": False,
2663        "ordinality": False,
2664        "when": False,
2665        "only": False,
2666    }
2667
2668    @property
2669    def name(self) -> str:
2670        if isinstance(self.this, Func):
2671            return ""
2672        return self.this.name
2673
2674    @property
2675    def db(self) -> str:
2676        return self.text("db")
2677
2678    @property
2679    def catalog(self) -> str:
2680        return self.text("catalog")
2681
2682    @property
2683    def selects(self) -> t.List[Expression]:
2684        return []
2685
2686    @property
2687    def named_selects(self) -> t.List[str]:
2688        return []
2689
2690    @property
2691    def parts(self) -> t.List[Expression]:
2692        """Return the parts of a table in order catalog, db, table."""
2693        parts: t.List[Expression] = []
2694
2695        for arg in ("catalog", "db", "this"):
2696            part = self.args.get(arg)
2697
2698            if isinstance(part, Dot):
2699                parts.extend(part.flatten())
2700            elif isinstance(part, Expression):
2701                parts.append(part)
2702
2703        return parts
2704
2705    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2706        parts = self.parts
2707        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2708        alias = self.args.get("alias")
2709        if alias:
2710            col = alias_(col, alias.this, copy=copy)
2711        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False}
name: str
2668    @property
2669    def name(self) -> str:
2670        if isinstance(self.this, Func):
2671            return ""
2672        return self.this.name
db: str
2674    @property
2675    def db(self) -> str:
2676        return self.text("db")
catalog: str
2678    @property
2679    def catalog(self) -> str:
2680        return self.text("catalog")
selects: List[Expression]
2682    @property
2683    def selects(self) -> t.List[Expression]:
2684        return []
named_selects: List[str]
2686    @property
2687    def named_selects(self) -> t.List[str]:
2688        return []
parts: List[Expression]
2690    @property
2691    def parts(self) -> t.List[Expression]:
2692        """Return the parts of a table in order catalog, db, table."""
2693        parts: t.List[Expression] = []
2694
2695        for arg in ("catalog", "db", "this"):
2696            part = self.args.get(arg)
2697
2698            if isinstance(part, Dot):
2699                parts.extend(part.flatten())
2700            elif isinstance(part, Expression):
2701                parts.append(part)
2702
2703        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2705    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2706        parts = self.parts
2707        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2708        alias = self.args.get("alias")
2709        if alias:
2710            col = alias_(col, alias.this, copy=copy)
2711        return col
key = 'table'
class Union(Query):
2714class Union(Query):
2715    arg_types = {
2716        "with": False,
2717        "this": True,
2718        "expression": True,
2719        "distinct": False,
2720        "by_name": False,
2721        **QUERY_MODIFIERS,
2722    }
2723
2724    def select(
2725        self,
2726        *expressions: t.Optional[ExpOrStr],
2727        append: bool = True,
2728        dialect: DialectType = None,
2729        copy: bool = True,
2730        **opts,
2731    ) -> Union:
2732        this = maybe_copy(self, copy)
2733        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2734        this.expression.unnest().select(
2735            *expressions, append=append, dialect=dialect, copy=False, **opts
2736        )
2737        return this
2738
2739    @property
2740    def named_selects(self) -> t.List[str]:
2741        return self.this.unnest().named_selects
2742
2743    @property
2744    def is_star(self) -> bool:
2745        return self.this.is_star or self.expression.is_star
2746
2747    @property
2748    def selects(self) -> t.List[Expression]:
2749        return self.this.unnest().selects
2750
2751    @property
2752    def left(self) -> Expression:
2753        return self.this
2754
2755    @property
2756    def right(self) -> Expression:
2757        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
2724    def select(
2725        self,
2726        *expressions: t.Optional[ExpOrStr],
2727        append: bool = True,
2728        dialect: DialectType = None,
2729        copy: bool = True,
2730        **opts,
2731    ) -> Union:
2732        this = maybe_copy(self, copy)
2733        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2734        this.expression.unnest().select(
2735            *expressions, append=append, dialect=dialect, copy=False, **opts
2736        )
2737        return this

Append to or set the SELECT expressions.

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

The modified Query expression.

named_selects: List[str]
2739    @property
2740    def named_selects(self) -> t.List[str]:
2741        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2743    @property
2744    def is_star(self) -> bool:
2745        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2747    @property
2748    def selects(self) -> t.List[Expression]:
2749        return self.this.unnest().selects

Returns the query's projections.

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

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:
2873    def group_by(
2874        self,
2875        *expressions: t.Optional[ExpOrStr],
2876        append: bool = True,
2877        dialect: DialectType = None,
2878        copy: bool = True,
2879        **opts,
2880    ) -> Select:
2881        """
2882        Set the GROUP BY expression.
2883
2884        Example:
2885            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2886            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2887
2888        Args:
2889            *expressions: the SQL code strings to parse.
2890                If a `Group` instance is passed, this is used as-is.
2891                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2892                If nothing is passed in then a group by is not applied to the expression
2893            append: if `True`, add to any existing expressions.
2894                Otherwise, this flattens all the `Group` expression into a single expression.
2895            dialect: the dialect used to parse the input expression.
2896            copy: if `False`, modify this expression instance in-place.
2897            opts: other options to use to parse the input expressions.
2898
2899        Returns:
2900            The modified Select expression.
2901        """
2902        if not expressions:
2903            return self if not copy else self.copy()
2904
2905        return _apply_child_list_builder(
2906            *expressions,
2907            instance=self,
2908            arg="group",
2909            append=append,
2910            copy=copy,
2911            prefix="GROUP BY",
2912            into=Group,
2913            dialect=dialect,
2914            **opts,
2915        )

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

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:
2957    def sort_by(
2958        self,
2959        *expressions: t.Optional[ExpOrStr],
2960        append: bool = True,
2961        dialect: DialectType = None,
2962        copy: bool = True,
2963        **opts,
2964    ) -> Select:
2965        """
2966        Set the SORT BY expression.
2967
2968        Example:
2969            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2970            'SELECT x FROM tbl SORT BY x DESC'
2971
2972        Args:
2973            *expressions: the SQL code strings to parse.
2974                If a `Group` instance is passed, this is used as-is.
2975                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2976            append: if `True`, add to any existing expressions.
2977                Otherwise, this flattens all the `Order` expression into a single expression.
2978            dialect: the dialect used to parse the input expression.
2979            copy: if `False`, modify this expression instance in-place.
2980            opts: other options to use to parse the input expressions.
2981
2982        Returns:
2983            The modified Select expression.
2984        """
2985        return _apply_child_list_builder(
2986            *expressions,
2987            instance=self,
2988            arg="sort",
2989            append=append,
2990            copy=copy,
2991            prefix="SORT BY",
2992            into=Sort,
2993            dialect=dialect,
2994            **opts,
2995        )

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

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:
3037    def limit(
3038        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3039    ) -> Select:
3040        return _apply_builder(
3041            expression=expression,
3042            instance=self,
3043            arg="limit",
3044            into=Limit,
3045            prefix="LIMIT",
3046            dialect=dialect,
3047            copy=copy,
3048            into_arg="expression",
3049            **opts,
3050        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

def offset( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3052    def offset(
3053        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3054    ) -> Select:
3055        """
3056        Set the OFFSET expression.
3057
3058        Example:
3059            >>> Select().from_("tbl").select("x").offset(10).sql()
3060            'SELECT x FROM tbl OFFSET 10'
3061
3062        Args:
3063            expression: the SQL code string to parse.
3064                This can also be an integer.
3065                If a `Offset` instance is passed, this is used as-is.
3066                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3067            dialect: the dialect used to parse the input expression.
3068            copy: if `False`, modify this expression instance in-place.
3069            opts: other options to use to parse the input expressions.
3070
3071        Returns:
3072            The modified Select expression.
3073        """
3074        return _apply_builder(
3075            expression=expression,
3076            instance=self,
3077            arg="offset",
3078            into=Offset,
3079            prefix="OFFSET",
3080            dialect=dialect,
3081            copy=copy,
3082            into_arg="expression",
3083            **opts,
3084        )

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:
3086    def select(
3087        self,
3088        *expressions: t.Optional[ExpOrStr],
3089        append: bool = True,
3090        dialect: DialectType = None,
3091        copy: bool = True,
3092        **opts,
3093    ) -> Select:
3094        return _apply_list_builder(
3095            *expressions,
3096            instance=self,
3097            arg="expressions",
3098            append=append,
3099            dialect=dialect,
3100            into=Expression,
3101            copy=copy,
3102            **opts,
3103        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3105    def lateral(
3106        self,
3107        *expressions: t.Optional[ExpOrStr],
3108        append: bool = True,
3109        dialect: DialectType = None,
3110        copy: bool = True,
3111        **opts,
3112    ) -> Select:
3113        """
3114        Append to or set the LATERAL expressions.
3115
3116        Example:
3117            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3118            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3119
3120        Args:
3121            *expressions: the SQL code strings to parse.
3122                If an `Expression` instance is passed, it will be used as-is.
3123            append: if `True`, add to any existing expressions.
3124                Otherwise, this resets the expressions.
3125            dialect: the dialect used to parse the input expressions.
3126            copy: if `False`, modify this expression instance in-place.
3127            opts: other options to use to parse the input expressions.
3128
3129        Returns:
3130            The modified Select expression.
3131        """
3132        return _apply_list_builder(
3133            *expressions,
3134            instance=self,
3135            arg="laterals",
3136            append=append,
3137            into=Lateral,
3138            prefix="LATERAL VIEW",
3139            dialect=dialect,
3140            copy=copy,
3141            **opts,
3142        )

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:
3144    def join(
3145        self,
3146        expression: ExpOrStr,
3147        on: t.Optional[ExpOrStr] = None,
3148        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3149        append: bool = True,
3150        join_type: t.Optional[str] = None,
3151        join_alias: t.Optional[Identifier | str] = None,
3152        dialect: DialectType = None,
3153        copy: bool = True,
3154        **opts,
3155    ) -> Select:
3156        """
3157        Append to or set the JOIN expressions.
3158
3159        Example:
3160            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3161            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3162
3163            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3164            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3165
3166            Use `join_type` to change the type of join:
3167
3168            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3169            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3170
3171        Args:
3172            expression: the SQL code string to parse.
3173                If an `Expression` instance is passed, it will be used as-is.
3174            on: optionally specify the join "on" criteria as a SQL string.
3175                If an `Expression` instance is passed, it will be used as-is.
3176            using: optionally specify the join "using" criteria as a SQL string.
3177                If an `Expression` instance is passed, it will be used as-is.
3178            append: if `True`, add to any existing expressions.
3179                Otherwise, this resets the expressions.
3180            join_type: if set, alter the parsed join type.
3181            join_alias: an optional alias for the joined source.
3182            dialect: the dialect used to parse the input expressions.
3183            copy: if `False`, modify this expression instance in-place.
3184            opts: other options to use to parse the input expressions.
3185
3186        Returns:
3187            Select: the modified expression.
3188        """
3189        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3190
3191        try:
3192            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3193        except ParseError:
3194            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3195
3196        join = expression if isinstance(expression, Join) else Join(this=expression)
3197
3198        if isinstance(join.this, Select):
3199            join.this.replace(join.this.subquery())
3200
3201        if join_type:
3202            method: t.Optional[Token]
3203            side: t.Optional[Token]
3204            kind: t.Optional[Token]
3205
3206            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3207
3208            if method:
3209                join.set("method", method.text)
3210            if side:
3211                join.set("side", side.text)
3212            if kind:
3213                join.set("kind", kind.text)
3214
3215        if on:
3216            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3217            join.set("on", on)
3218
3219        if using:
3220            join = _apply_list_builder(
3221                *ensure_list(using),
3222                instance=join,
3223                arg="using",
3224                append=append,
3225                copy=copy,
3226                into=Identifier,
3227                **opts,
3228            )
3229
3230        if join_alias:
3231            join.set("this", alias_(join.this, join_alias, table=True))
3232
3233        return _apply_list_builder(
3234            join,
3235            instance=self,
3236            arg="joins",
3237            append=append,
3238            copy=copy,
3239            **opts,
3240        )

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

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:
3281    def having(
3282        self,
3283        *expressions: t.Optional[ExpOrStr],
3284        append: bool = True,
3285        dialect: DialectType = None,
3286        copy: bool = True,
3287        **opts,
3288    ) -> Select:
3289        """
3290        Append to or set the HAVING expressions.
3291
3292        Example:
3293            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3294            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3295
3296        Args:
3297            *expressions: the SQL code strings to parse.
3298                If an `Expression` instance is passed, it will be used as-is.
3299                Multiple expressions are combined with an AND operator.
3300            append: if `True`, AND the new expressions to any existing expression.
3301                Otherwise, this resets the expression.
3302            dialect: the dialect used to parse the input expressions.
3303            copy: if `False`, modify this expression instance in-place.
3304            opts: other options to use to parse the input expressions.
3305
3306        Returns:
3307            The modified Select expression.
3308        """
3309        return _apply_conjunction_builder(
3310            *expressions,
3311            instance=self,
3312            arg="having",
3313            append=append,
3314            into=Having,
3315            dialect=dialect,
3316            copy=copy,
3317            **opts,
3318        )

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:
3320    def window(
3321        self,
3322        *expressions: t.Optional[ExpOrStr],
3323        append: bool = True,
3324        dialect: DialectType = None,
3325        copy: bool = True,
3326        **opts,
3327    ) -> Select:
3328        return _apply_list_builder(
3329            *expressions,
3330            instance=self,
3331            arg="windows",
3332            append=append,
3333            into=Window,
3334            dialect=dialect,
3335            copy=copy,
3336            **opts,
3337        )
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:
3339    def qualify(
3340        self,
3341        *expressions: t.Optional[ExpOrStr],
3342        append: bool = True,
3343        dialect: DialectType = None,
3344        copy: bool = True,
3345        **opts,
3346    ) -> Select:
3347        return _apply_conjunction_builder(
3348            *expressions,
3349            instance=self,
3350            arg="qualify",
3351            append=append,
3352            into=Qualify,
3353            dialect=dialect,
3354            copy=copy,
3355            **opts,
3356        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3358    def distinct(
3359        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3360    ) -> Select:
3361        """
3362        Set the OFFSET expression.
3363
3364        Example:
3365            >>> Select().from_("tbl").select("x").distinct().sql()
3366            'SELECT DISTINCT x FROM tbl'
3367
3368        Args:
3369            ons: the expressions to distinct on
3370            distinct: whether the Select should be distinct
3371            copy: if `False`, modify this expression instance in-place.
3372
3373        Returns:
3374            Select: the modified expression.
3375        """
3376        instance = maybe_copy(self, copy)
3377        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3378        instance.set("distinct", Distinct(on=on) if distinct else None)
3379        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:
3381    def ctas(
3382        self,
3383        table: ExpOrStr,
3384        properties: t.Optional[t.Dict] = None,
3385        dialect: DialectType = None,
3386        copy: bool = True,
3387        **opts,
3388    ) -> Create:
3389        """
3390        Convert this expression to a CREATE TABLE AS statement.
3391
3392        Example:
3393            >>> Select().select("*").from_("tbl").ctas("x").sql()
3394            'CREATE TABLE x AS SELECT * FROM tbl'
3395
3396        Args:
3397            table: the SQL code string to parse as the table name.
3398                If another `Expression` instance is passed, it will be used as-is.
3399            properties: an optional mapping of table properties
3400            dialect: the dialect used to parse the input table.
3401            copy: if `False`, modify this expression instance in-place.
3402            opts: other options to use to parse the input table.
3403
3404        Returns:
3405            The new Create expression.
3406        """
3407        instance = maybe_copy(self, copy)
3408        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3409
3410        properties_expression = None
3411        if properties:
3412            properties_expression = Properties.from_dict(properties)
3413
3414        return Create(
3415            this=table_expression,
3416            kind="TABLE",
3417            expression=instance,
3418            properties=properties_expression,
3419        )

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:
3421    def lock(self, update: bool = True, copy: bool = True) -> Select:
3422        """
3423        Set the locking read mode for this expression.
3424
3425        Examples:
3426            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3427            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3428
3429            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3430            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3431
3432        Args:
3433            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3434            copy: if `False`, modify this expression instance in-place.
3435
3436        Returns:
3437            The modified expression.
3438        """
3439        inst = maybe_copy(self, copy)
3440        inst.set("locks", [Lock(update=update)])
3441
3442        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:
3444    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3445        """
3446        Set hints for this expression.
3447
3448        Examples:
3449            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3450            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3451
3452        Args:
3453            hints: The SQL code strings to parse as the hints.
3454                If an `Expression` instance is passed, it will be used as-is.
3455            dialect: The dialect used to parse the hints.
3456            copy: If `False`, modify this expression instance in-place.
3457
3458        Returns:
3459            The modified expression.
3460        """
3461        inst = maybe_copy(self, copy)
3462        inst.set(
3463            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3464        )
3465
3466        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]
3468    @property
3469    def named_selects(self) -> t.List[str]:
3470        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
3472    @property
3473    def is_star(self) -> bool:
3474        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3476    @property
3477    def selects(self) -> t.List[Expression]:
3478        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3484class Subquery(DerivedTable, Query):
3485    arg_types = {
3486        "this": True,
3487        "alias": False,
3488        "with": False,
3489        **QUERY_MODIFIERS,
3490    }
3491
3492    def unnest(self):
3493        """Returns the first non subquery."""
3494        expression = self
3495        while isinstance(expression, Subquery):
3496            expression = expression.this
3497        return expression
3498
3499    def unwrap(self) -> Subquery:
3500        expression = self
3501        while expression.same_parent and expression.is_wrapper:
3502            expression = t.cast(Subquery, expression.parent)
3503        return expression
3504
3505    def select(
3506        self,
3507        *expressions: t.Optional[ExpOrStr],
3508        append: bool = True,
3509        dialect: DialectType = None,
3510        copy: bool = True,
3511        **opts,
3512    ) -> Subquery:
3513        this = maybe_copy(self, copy)
3514        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3515        return this
3516
3517    @property
3518    def is_wrapper(self) -> bool:
3519        """
3520        Whether this Subquery acts as a simple wrapper around another expression.
3521
3522        SELECT * FROM (((SELECT * FROM t)))
3523                      ^
3524                      This corresponds to a "wrapper" Subquery node
3525        """
3526        return all(v is None for k, v in self.args.items() if k != "this")
3527
3528    @property
3529    def is_star(self) -> bool:
3530        return self.this.is_star
3531
3532    @property
3533    def output_name(self) -> str:
3534        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def unnest(self):
3492    def unnest(self):
3493        """Returns the first non subquery."""
3494        expression = self
3495        while isinstance(expression, Subquery):
3496            expression = expression.this
3497        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3499    def unwrap(self) -> Subquery:
3500        expression = self
3501        while expression.same_parent and expression.is_wrapper:
3502            expression = t.cast(Subquery, expression.parent)
3503        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
3505    def select(
3506        self,
3507        *expressions: t.Optional[ExpOrStr],
3508        append: bool = True,
3509        dialect: DialectType = None,
3510        copy: bool = True,
3511        **opts,
3512    ) -> Subquery:
3513        this = maybe_copy(self, copy)
3514        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3515        return this

Append to or set the SELECT expressions.

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

The modified Query expression.

is_wrapper: bool
3517    @property
3518    def is_wrapper(self) -> bool:
3519        """
3520        Whether this Subquery acts as a simple wrapper around another expression.
3521
3522        SELECT * FROM (((SELECT * FROM t)))
3523                      ^
3524                      This corresponds to a "wrapper" Subquery node
3525        """
3526        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
3528    @property
3529    def is_star(self) -> bool:
3530        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3532    @property
3533    def output_name(self) -> str:
3534        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):
3537class TableSample(Expression):
3538    arg_types = {
3539        "this": False,
3540        "expressions": False,
3541        "method": False,
3542        "bucket_numerator": False,
3543        "bucket_denominator": False,
3544        "bucket_field": False,
3545        "percent": False,
3546        "rows": False,
3547        "size": False,
3548        "seed": False,
3549    }
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):
3552class Tag(Expression):
3553    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3554
3555    arg_types = {
3556        "this": False,
3557        "prefix": False,
3558        "postfix": False,
3559    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3564class Pivot(Expression):
3565    arg_types = {
3566        "this": False,
3567        "alias": False,
3568        "expressions": False,
3569        "field": False,
3570        "unpivot": False,
3571        "using": False,
3572        "group": False,
3573        "columns": False,
3574        "include_nulls": False,
3575    }
3576
3577    @property
3578    def unpivot(self) -> bool:
3579        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
3577    @property
3578    def unpivot(self) -> bool:
3579        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3582class Window(Condition):
3583    arg_types = {
3584        "this": True,
3585        "partition_by": False,
3586        "order": False,
3587        "spec": False,
3588        "alias": False,
3589        "over": False,
3590        "first": False,
3591    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3594class WindowSpec(Expression):
3595    arg_types = {
3596        "kind": False,
3597        "start": False,
3598        "start_side": False,
3599        "end": False,
3600        "end_side": False,
3601    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3604class PreWhere(Expression):
3605    pass
key = 'prewhere'
class Where(Expression):
3608class Where(Expression):
3609    pass
key = 'where'
class Star(Expression):
3612class Star(Expression):
3613    arg_types = {"except": False, "replace": False}
3614
3615    @property
3616    def name(self) -> str:
3617        return "*"
3618
3619    @property
3620    def output_name(self) -> str:
3621        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3615    @property
3616    def name(self) -> str:
3617        return "*"
output_name: str
3619    @property
3620    def output_name(self) -> str:
3621        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):
3624class Parameter(Condition):
3625    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3628class SessionParameter(Condition):
3629    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3632class Placeholder(Condition):
3633    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3636class Null(Condition):
3637    arg_types: t.Dict[str, t.Any] = {}
3638
3639    @property
3640    def name(self) -> str:
3641        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3639    @property
3640    def name(self) -> str:
3641        return "NULL"
key = 'null'
class Boolean(Condition):
3644class Boolean(Condition):
3645    pass
key = 'boolean'
class DataTypeParam(Expression):
3648class DataTypeParam(Expression):
3649    arg_types = {"this": True, "expression": False}
3650
3651    @property
3652    def name(self) -> str:
3653        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3651    @property
3652    def name(self) -> str:
3653        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3656class DataType(Expression):
3657    arg_types = {
3658        "this": True,
3659        "expressions": False,
3660        "nested": False,
3661        "values": False,
3662        "prefix": False,
3663        "kind": False,
3664    }
3665
3666    class Type(AutoName):
3667        ARRAY = auto()
3668        AGGREGATEFUNCTION = auto()
3669        SIMPLEAGGREGATEFUNCTION = auto()
3670        BIGDECIMAL = auto()
3671        BIGINT = auto()
3672        BIGSERIAL = auto()
3673        BINARY = auto()
3674        BIT = auto()
3675        BOOLEAN = auto()
3676        BPCHAR = auto()
3677        CHAR = auto()
3678        DATE = auto()
3679        DATE32 = auto()
3680        DATEMULTIRANGE = auto()
3681        DATERANGE = auto()
3682        DATETIME = auto()
3683        DATETIME64 = auto()
3684        DECIMAL = auto()
3685        DOUBLE = auto()
3686        ENUM = auto()
3687        ENUM8 = auto()
3688        ENUM16 = auto()
3689        FIXEDSTRING = auto()
3690        FLOAT = auto()
3691        GEOGRAPHY = auto()
3692        GEOMETRY = auto()
3693        HLLSKETCH = auto()
3694        HSTORE = auto()
3695        IMAGE = auto()
3696        INET = auto()
3697        INT = auto()
3698        INT128 = auto()
3699        INT256 = auto()
3700        INT4MULTIRANGE = auto()
3701        INT4RANGE = auto()
3702        INT8MULTIRANGE = auto()
3703        INT8RANGE = auto()
3704        INTERVAL = auto()
3705        IPADDRESS = auto()
3706        IPPREFIX = auto()
3707        IPV4 = auto()
3708        IPV6 = auto()
3709        JSON = auto()
3710        JSONB = auto()
3711        LONGBLOB = auto()
3712        LONGTEXT = auto()
3713        LOWCARDINALITY = auto()
3714        MAP = auto()
3715        MEDIUMBLOB = auto()
3716        MEDIUMINT = auto()
3717        MEDIUMTEXT = auto()
3718        MONEY = auto()
3719        NCHAR = auto()
3720        NESTED = auto()
3721        NULL = auto()
3722        NULLABLE = auto()
3723        NUMMULTIRANGE = auto()
3724        NUMRANGE = auto()
3725        NVARCHAR = auto()
3726        OBJECT = auto()
3727        ROWVERSION = auto()
3728        SERIAL = auto()
3729        SET = auto()
3730        SMALLINT = auto()
3731        SMALLMONEY = auto()
3732        SMALLSERIAL = auto()
3733        STRUCT = auto()
3734        SUPER = auto()
3735        TEXT = auto()
3736        TINYBLOB = auto()
3737        TINYTEXT = auto()
3738        TIME = auto()
3739        TIMETZ = auto()
3740        TIMESTAMP = auto()
3741        TIMESTAMPLTZ = auto()
3742        TIMESTAMPTZ = auto()
3743        TIMESTAMP_S = auto()
3744        TIMESTAMP_MS = auto()
3745        TIMESTAMP_NS = auto()
3746        TINYINT = auto()
3747        TSMULTIRANGE = auto()
3748        TSRANGE = auto()
3749        TSTZMULTIRANGE = auto()
3750        TSTZRANGE = auto()
3751        UBIGINT = auto()
3752        UINT = auto()
3753        UINT128 = auto()
3754        UINT256 = auto()
3755        UMEDIUMINT = auto()
3756        UDECIMAL = auto()
3757        UNIQUEIDENTIFIER = auto()
3758        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3759        USERDEFINED = "USER-DEFINED"
3760        USMALLINT = auto()
3761        UTINYINT = auto()
3762        UUID = auto()
3763        VARBINARY = auto()
3764        VARCHAR = auto()
3765        VARIANT = auto()
3766        XML = auto()
3767        YEAR = auto()
3768
3769    TEXT_TYPES = {
3770        Type.CHAR,
3771        Type.NCHAR,
3772        Type.VARCHAR,
3773        Type.NVARCHAR,
3774        Type.TEXT,
3775    }
3776
3777    INTEGER_TYPES = {
3778        Type.INT,
3779        Type.TINYINT,
3780        Type.SMALLINT,
3781        Type.BIGINT,
3782        Type.INT128,
3783        Type.INT256,
3784        Type.BIT,
3785    }
3786
3787    FLOAT_TYPES = {
3788        Type.FLOAT,
3789        Type.DOUBLE,
3790    }
3791
3792    NUMERIC_TYPES = {
3793        *INTEGER_TYPES,
3794        *FLOAT_TYPES,
3795    }
3796
3797    TEMPORAL_TYPES = {
3798        Type.TIME,
3799        Type.TIMETZ,
3800        Type.TIMESTAMP,
3801        Type.TIMESTAMPTZ,
3802        Type.TIMESTAMPLTZ,
3803        Type.TIMESTAMP_S,
3804        Type.TIMESTAMP_MS,
3805        Type.TIMESTAMP_NS,
3806        Type.DATE,
3807        Type.DATE32,
3808        Type.DATETIME,
3809        Type.DATETIME64,
3810    }
3811
3812    @classmethod
3813    def build(
3814        cls,
3815        dtype: DATA_TYPE,
3816        dialect: DialectType = None,
3817        udt: bool = False,
3818        copy: bool = True,
3819        **kwargs,
3820    ) -> DataType:
3821        """
3822        Constructs a DataType object.
3823
3824        Args:
3825            dtype: the data type of interest.
3826            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3827            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3828                DataType, thus creating a user-defined type.
3829            copy: whether to copy the data type.
3830            kwargs: additional arguments to pass in the constructor of DataType.
3831
3832        Returns:
3833            The constructed DataType object.
3834        """
3835        from sqlglot import parse_one
3836
3837        if isinstance(dtype, str):
3838            if dtype.upper() == "UNKNOWN":
3839                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3840
3841            try:
3842                data_type_exp = parse_one(
3843                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3844                )
3845            except ParseError:
3846                if udt:
3847                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3848                raise
3849        elif isinstance(dtype, DataType.Type):
3850            data_type_exp = DataType(this=dtype)
3851        elif isinstance(dtype, DataType):
3852            return maybe_copy(dtype, copy)
3853        else:
3854            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3855
3856        return DataType(**{**data_type_exp.args, **kwargs})
3857
3858    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3859        """
3860        Checks whether this DataType matches one of the provided data types. Nested types or precision
3861        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3862
3863        Args:
3864            dtypes: the data types to compare this DataType to.
3865
3866        Returns:
3867            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3868        """
3869        for dtype in dtypes:
3870            other = DataType.build(dtype, copy=False, udt=True)
3871
3872            if (
3873                other.expressions
3874                or self.this == DataType.Type.USERDEFINED
3875                or other.this == DataType.Type.USERDEFINED
3876            ):
3877                matches = self == other
3878            else:
3879                matches = self.this == other.this
3880
3881            if matches:
3882                return True
3883        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLINT: 'SMALLINT'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
3812    @classmethod
3813    def build(
3814        cls,
3815        dtype: DATA_TYPE,
3816        dialect: DialectType = None,
3817        udt: bool = False,
3818        copy: bool = True,
3819        **kwargs,
3820    ) -> DataType:
3821        """
3822        Constructs a DataType object.
3823
3824        Args:
3825            dtype: the data type of interest.
3826            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3827            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3828                DataType, thus creating a user-defined type.
3829            copy: whether to copy the data type.
3830            kwargs: additional arguments to pass in the constructor of DataType.
3831
3832        Returns:
3833            The constructed DataType object.
3834        """
3835        from sqlglot import parse_one
3836
3837        if isinstance(dtype, str):
3838            if dtype.upper() == "UNKNOWN":
3839                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3840
3841            try:
3842                data_type_exp = parse_one(
3843                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3844                )
3845            except ParseError:
3846                if udt:
3847                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3848                raise
3849        elif isinstance(dtype, DataType.Type):
3850            data_type_exp = DataType(this=dtype)
3851        elif isinstance(dtype, DataType):
3852            return maybe_copy(dtype, copy)
3853        else:
3854            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3855
3856        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

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

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
3858    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3859        """
3860        Checks whether this DataType matches one of the provided data types. Nested types or precision
3861        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3862
3863        Args:
3864            dtypes: the data types to compare this DataType to.
3865
3866        Returns:
3867            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3868        """
3869        for dtype in dtypes:
3870            other = DataType.build(dtype, copy=False, udt=True)
3871
3872            if (
3873                other.expressions
3874                or self.this == DataType.Type.USERDEFINED
3875                or other.this == DataType.Type.USERDEFINED
3876            ):
3877                matches = self == other
3878            else:
3879                matches = self.this == other.this
3880
3881            if matches:
3882                return True
3883        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):
3666    class Type(AutoName):
3667        ARRAY = auto()
3668        AGGREGATEFUNCTION = auto()
3669        SIMPLEAGGREGATEFUNCTION = auto()
3670        BIGDECIMAL = auto()
3671        BIGINT = auto()
3672        BIGSERIAL = auto()
3673        BINARY = auto()
3674        BIT = auto()
3675        BOOLEAN = auto()
3676        BPCHAR = auto()
3677        CHAR = auto()
3678        DATE = auto()
3679        DATE32 = auto()
3680        DATEMULTIRANGE = auto()
3681        DATERANGE = auto()
3682        DATETIME = auto()
3683        DATETIME64 = auto()
3684        DECIMAL = auto()
3685        DOUBLE = auto()
3686        ENUM = auto()
3687        ENUM8 = auto()
3688        ENUM16 = auto()
3689        FIXEDSTRING = auto()
3690        FLOAT = auto()
3691        GEOGRAPHY = auto()
3692        GEOMETRY = auto()
3693        HLLSKETCH = auto()
3694        HSTORE = auto()
3695        IMAGE = auto()
3696        INET = auto()
3697        INT = auto()
3698        INT128 = auto()
3699        INT256 = auto()
3700        INT4MULTIRANGE = auto()
3701        INT4RANGE = auto()
3702        INT8MULTIRANGE = auto()
3703        INT8RANGE = auto()
3704        INTERVAL = auto()
3705        IPADDRESS = auto()
3706        IPPREFIX = auto()
3707        IPV4 = auto()
3708        IPV6 = auto()
3709        JSON = auto()
3710        JSONB = auto()
3711        LONGBLOB = auto()
3712        LONGTEXT = auto()
3713        LOWCARDINALITY = auto()
3714        MAP = auto()
3715        MEDIUMBLOB = auto()
3716        MEDIUMINT = auto()
3717        MEDIUMTEXT = auto()
3718        MONEY = auto()
3719        NCHAR = auto()
3720        NESTED = auto()
3721        NULL = auto()
3722        NULLABLE = auto()
3723        NUMMULTIRANGE = auto()
3724        NUMRANGE = auto()
3725        NVARCHAR = auto()
3726        OBJECT = auto()
3727        ROWVERSION = auto()
3728        SERIAL = auto()
3729        SET = auto()
3730        SMALLINT = auto()
3731        SMALLMONEY = auto()
3732        SMALLSERIAL = auto()
3733        STRUCT = auto()
3734        SUPER = auto()
3735        TEXT = auto()
3736        TINYBLOB = auto()
3737        TINYTEXT = auto()
3738        TIME = auto()
3739        TIMETZ = auto()
3740        TIMESTAMP = auto()
3741        TIMESTAMPLTZ = auto()
3742        TIMESTAMPTZ = auto()
3743        TIMESTAMP_S = auto()
3744        TIMESTAMP_MS = auto()
3745        TIMESTAMP_NS = auto()
3746        TINYINT = auto()
3747        TSMULTIRANGE = auto()
3748        TSRANGE = auto()
3749        TSTZMULTIRANGE = auto()
3750        TSTZRANGE = auto()
3751        UBIGINT = auto()
3752        UINT = auto()
3753        UINT128 = auto()
3754        UINT256 = auto()
3755        UMEDIUMINT = auto()
3756        UDECIMAL = auto()
3757        UNIQUEIDENTIFIER = auto()
3758        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3759        USERDEFINED = "USER-DEFINED"
3760        USMALLINT = auto()
3761        UTINYINT = auto()
3762        UUID = auto()
3763        VARBINARY = auto()
3764        VARCHAR = auto()
3765        VARIANT = auto()
3766        XML = auto()
3767        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
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):
3890class PseudoType(DataType):
3891    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3895class ObjectIdentifier(DataType):
3896    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3900class SubqueryPredicate(Predicate):
3901    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3904class All(SubqueryPredicate):
3905    pass
key = 'all'
class Any(SubqueryPredicate):
3908class Any(SubqueryPredicate):
3909    pass
key = 'any'
class Exists(SubqueryPredicate):
3912class Exists(SubqueryPredicate):
3913    pass
key = 'exists'
class Command(Expression):
3918class Command(Expression):
3919    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3922class Transaction(Expression):
3923    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3926class Commit(Expression):
3927    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3930class Rollback(Expression):
3931    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3934class AlterTable(Expression):
3935    arg_types = {
3936        "this": True,
3937        "actions": True,
3938        "exists": False,
3939        "only": False,
3940        "options": False,
3941    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
3944class AddConstraint(Expression):
3945    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
3948class DropPartition(Expression):
3949    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3953class Binary(Condition):
3954    arg_types = {"this": True, "expression": True}
3955
3956    @property
3957    def left(self) -> Expression:
3958        return self.this
3959
3960    @property
3961    def right(self) -> Expression:
3962        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3956    @property
3957    def left(self) -> Expression:
3958        return self.this
right: Expression
3960    @property
3961    def right(self) -> Expression:
3962        return self.expression
key = 'binary'
class Add(Binary):
3965class Add(Binary):
3966    pass
key = 'add'
class Connector(Binary):
3969class Connector(Binary):
3970    pass
key = 'connector'
class And(Connector):
3973class And(Connector):
3974    pass
key = 'and'
class Or(Connector):
3977class Or(Connector):
3978    pass
key = 'or'
class BitwiseAnd(Binary):
3981class BitwiseAnd(Binary):
3982    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3985class BitwiseLeftShift(Binary):
3986    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3989class BitwiseOr(Binary):
3990    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3993class BitwiseRightShift(Binary):
3994    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3997class BitwiseXor(Binary):
3998    pass
key = 'bitwisexor'
class Div(Binary):
4001class Div(Binary):
4002    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):
4005class Overlaps(Binary):
4006    pass
key = 'overlaps'
class Dot(Binary):
4009class Dot(Binary):
4010    @property
4011    def is_star(self) -> bool:
4012        return self.expression.is_star
4013
4014    @property
4015    def name(self) -> str:
4016        return self.expression.name
4017
4018    @property
4019    def output_name(self) -> str:
4020        return self.name
4021
4022    @classmethod
4023    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4024        """Build a Dot object with a sequence of expressions."""
4025        if len(expressions) < 2:
4026            raise ValueError("Dot requires >= 2 expressions.")
4027
4028        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4029
4030    @property
4031    def parts(self) -> t.List[Expression]:
4032        """Return the parts of a table / column in order catalog, db, table."""
4033        this, *parts = self.flatten()
4034
4035        parts.reverse()
4036
4037        for arg in ("this", "table", "db", "catalog"):
4038            part = this.args.get(arg)
4039
4040            if isinstance(part, Expression):
4041                parts.append(part)
4042
4043        parts.reverse()
4044        return parts
is_star: bool
4010    @property
4011    def is_star(self) -> bool:
4012        return self.expression.is_star

Checks whether an expression is a star.

name: str
4014    @property
4015    def name(self) -> str:
4016        return self.expression.name
output_name: str
4018    @property
4019    def output_name(self) -> str:
4020        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:
4022    @classmethod
4023    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4024        """Build a Dot object with a sequence of expressions."""
4025        if len(expressions) < 2:
4026            raise ValueError("Dot requires >= 2 expressions.")
4027
4028        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]
4030    @property
4031    def parts(self) -> t.List[Expression]:
4032        """Return the parts of a table / column in order catalog, db, table."""
4033        this, *parts = self.flatten()
4034
4035        parts.reverse()
4036
4037        for arg in ("this", "table", "db", "catalog"):
4038            part = this.args.get(arg)
4039
4040            if isinstance(part, Expression):
4041                parts.append(part)
4042
4043        parts.reverse()
4044        return parts

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

key = 'dot'
class DPipe(Binary):
4047class DPipe(Binary):
4048    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4051class EQ(Binary, Predicate):
4052    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4055class NullSafeEQ(Binary, Predicate):
4056    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4059class NullSafeNEQ(Binary, Predicate):
4060    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4064class PropertyEQ(Binary):
4065    pass
key = 'propertyeq'
class Distance(Binary):
4068class Distance(Binary):
4069    pass
key = 'distance'
class Escape(Binary):
4072class Escape(Binary):
4073    pass
key = 'escape'
class Glob(Binary, Predicate):
4076class Glob(Binary, Predicate):
4077    pass
key = 'glob'
class GT(Binary, Predicate):
4080class GT(Binary, Predicate):
4081    pass
key = 'gt'
class GTE(Binary, Predicate):
4084class GTE(Binary, Predicate):
4085    pass
key = 'gte'
class ILike(Binary, Predicate):
4088class ILike(Binary, Predicate):
4089    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4092class ILikeAny(Binary, Predicate):
4093    pass
key = 'ilikeany'
class IntDiv(Binary):
4096class IntDiv(Binary):
4097    pass
key = 'intdiv'
class Is(Binary, Predicate):
4100class Is(Binary, Predicate):
4101    pass
key = 'is'
class Kwarg(Binary):
4104class Kwarg(Binary):
4105    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4108class Like(Binary, Predicate):
4109    pass
key = 'like'
class LikeAny(Binary, Predicate):
4112class LikeAny(Binary, Predicate):
4113    pass
key = 'likeany'
class LT(Binary, Predicate):
4116class LT(Binary, Predicate):
4117    pass
key = 'lt'
class LTE(Binary, Predicate):
4120class LTE(Binary, Predicate):
4121    pass
key = 'lte'
class Mod(Binary):
4124class Mod(Binary):
4125    pass
key = 'mod'
class Mul(Binary):
4128class Mul(Binary):
4129    pass
key = 'mul'
class NEQ(Binary, Predicate):
4132class NEQ(Binary, Predicate):
4133    pass
key = 'neq'
class Operator(Binary):
4137class Operator(Binary):
4138    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4141class SimilarTo(Binary, Predicate):
4142    pass
key = 'similarto'
class Slice(Binary):
4145class Slice(Binary):
4146    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4149class Sub(Binary):
4150    pass
key = 'sub'
class Unary(Condition):
4155class Unary(Condition):
4156    pass
key = 'unary'
class BitwiseNot(Unary):
4159class BitwiseNot(Unary):
4160    pass
key = 'bitwisenot'
class Not(Unary):
4163class Not(Unary):
4164    pass
key = 'not'
class Paren(Unary):
4167class Paren(Unary):
4168    arg_types = {"this": True, "with": False}
4169
4170    @property
4171    def output_name(self) -> str:
4172        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4170    @property
4171    def output_name(self) -> str:
4172        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):
4175class Neg(Unary):
4176    pass
key = 'neg'
class Alias(Expression):
4179class Alias(Expression):
4180    arg_types = {"this": True, "alias": False}
4181
4182    @property
4183    def output_name(self) -> str:
4184        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4182    @property
4183    def output_name(self) -> str:
4184        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):
4189class PivotAlias(Alias):
4190    pass
key = 'pivotalias'
class Aliases(Expression):
4193class Aliases(Expression):
4194    arg_types = {"this": True, "expressions": True}
4195
4196    @property
4197    def aliases(self):
4198        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4196    @property
4197    def aliases(self):
4198        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4202class AtIndex(Expression):
4203    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4206class AtTimeZone(Expression):
4207    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4210class FromTimeZone(Expression):
4211    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4214class Between(Predicate):
4215    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4218class Bracket(Condition):
4219    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4220    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4221
4222    @property
4223    def output_name(self) -> str:
4224        if len(self.expressions) == 1:
4225            return self.expressions[0].output_name
4226
4227        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4222    @property
4223    def output_name(self) -> str:
4224        if len(self.expressions) == 1:
4225            return self.expressions[0].output_name
4226
4227        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):
4230class Distinct(Expression):
4231    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4234class In(Predicate):
4235    arg_types = {
4236        "this": True,
4237        "expressions": False,
4238        "query": False,
4239        "unnest": False,
4240        "field": False,
4241        "is_global": False,
4242    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4246class ForIn(Expression):
4247    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4250class TimeUnit(Expression):
4251    """Automatically converts unit arg into a var."""
4252
4253    arg_types = {"unit": False}
4254
4255    UNABBREVIATED_UNIT_NAME = {
4256        "D": "DAY",
4257        "H": "HOUR",
4258        "M": "MINUTE",
4259        "MS": "MILLISECOND",
4260        "NS": "NANOSECOND",
4261        "Q": "QUARTER",
4262        "S": "SECOND",
4263        "US": "MICROSECOND",
4264        "W": "WEEK",
4265        "Y": "YEAR",
4266    }
4267
4268    VAR_LIKE = (Column, Literal, Var)
4269
4270    def __init__(self, **args):
4271        unit = args.get("unit")
4272        if isinstance(unit, self.VAR_LIKE):
4273            args["unit"] = Var(
4274                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4275            )
4276        elif isinstance(unit, Week):
4277            unit.set("this", Var(this=unit.this.name.upper()))
4278
4279        super().__init__(**args)
4280
4281    @property
4282    def unit(self) -> t.Optional[Var]:
4283        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4270    def __init__(self, **args):
4271        unit = args.get("unit")
4272        if isinstance(unit, self.VAR_LIKE):
4273            args["unit"] = Var(
4274                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4275            )
4276        elif isinstance(unit, Week):
4277            unit.set("this", Var(this=unit.this.name.upper()))
4278
4279        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]
4281    @property
4282    def unit(self) -> t.Optional[Var]:
4283        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4286class IntervalOp(TimeUnit):
4287    arg_types = {"unit": True, "expression": True}
4288
4289    def interval(self):
4290        return Interval(
4291            this=self.expression.copy(),
4292            unit=self.unit.copy(),
4293        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4289    def interval(self):
4290        return Interval(
4291            this=self.expression.copy(),
4292            unit=self.unit.copy(),
4293        )
key = 'intervalop'
class IntervalSpan(DataType):
4299class IntervalSpan(DataType):
4300    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4303class Interval(TimeUnit):
4304    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4307class IgnoreNulls(Expression):
4308    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4311class RespectNulls(Expression):
4312    pass
key = 'respectnulls'
class HavingMax(Expression):
4316class HavingMax(Expression):
4317    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4321class Func(Condition):
4322    """
4323    The base class for all function expressions.
4324
4325    Attributes:
4326        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4327            treated as a variable length argument and the argument's value will be stored as a list.
4328        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4329            function expression. These values are used to map this node to a name during parsing as
4330            well as to provide the function's name during SQL string generation. By default the SQL
4331            name is set to the expression's class name transformed to snake case.
4332    """
4333
4334    is_var_len_args = False
4335
4336    @classmethod
4337    def from_arg_list(cls, args):
4338        if cls.is_var_len_args:
4339            all_arg_keys = list(cls.arg_types)
4340            # If this function supports variable length argument treat the last argument as such.
4341            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4342            num_non_var = len(non_var_len_arg_keys)
4343
4344            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4345            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4346        else:
4347            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4348
4349        return cls(**args_dict)
4350
4351    @classmethod
4352    def sql_names(cls):
4353        if cls is Func:
4354            raise NotImplementedError(
4355                "SQL name is only supported by concrete function implementations"
4356            )
4357        if "_sql_names" not in cls.__dict__:
4358            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4359        return cls._sql_names
4360
4361    @classmethod
4362    def sql_name(cls):
4363        return cls.sql_names()[0]
4364
4365    @classmethod
4366    def default_parser_mappings(cls):
4367        return {name: cls.from_arg_list for name in cls.sql_names()}

The base class for all function expressions.

Attributes:
  • is_var_len_args (bool): if set to True the last argument defined in arg_types will be treated as a variable length argument and the argument's value will be stored as a list.
  • _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this function expression. These values are used to map this node to a name during parsing as well as to provide the function's name during SQL string generation. By default the SQL name is set to the expression's class name transformed to snake case.
is_var_len_args = False
@classmethod
def from_arg_list(cls, args):
4336    @classmethod
4337    def from_arg_list(cls, args):
4338        if cls.is_var_len_args:
4339            all_arg_keys = list(cls.arg_types)
4340            # If this function supports variable length argument treat the last argument as such.
4341            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4342            num_non_var = len(non_var_len_arg_keys)
4343
4344            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4345            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4346        else:
4347            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4348
4349        return cls(**args_dict)
@classmethod
def sql_names(cls):
4351    @classmethod
4352    def sql_names(cls):
4353        if cls is Func:
4354            raise NotImplementedError(
4355                "SQL name is only supported by concrete function implementations"
4356            )
4357        if "_sql_names" not in cls.__dict__:
4358            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4359        return cls._sql_names
@classmethod
def sql_name(cls):
4361    @classmethod
4362    def sql_name(cls):
4363        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4365    @classmethod
4366    def default_parser_mappings(cls):
4367        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4370class AggFunc(Func):
4371    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4374class ParameterizedAgg(AggFunc):
4375    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4378class Abs(Func):
4379    pass
key = 'abs'
class ArgMax(AggFunc):
4382class ArgMax(AggFunc):
4383    arg_types = {"this": True, "expression": True, "count": False}
4384    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4387class ArgMin(AggFunc):
4388    arg_types = {"this": True, "expression": True, "count": False}
4389    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4392class ApproxTopK(AggFunc):
4393    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4396class Flatten(Func):
4397    pass
key = 'flatten'
class Transform(Func):
4401class Transform(Func):
4402    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4405class Anonymous(Func):
4406    arg_types = {"this": True, "expressions": False}
4407    is_var_len_args = True
4408
4409    @property
4410    def name(self) -> str:
4411        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4409    @property
4410    def name(self) -> str:
4411        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4414class AnonymousAggFunc(AggFunc):
4415    arg_types = {"this": True, "expressions": False}
4416    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4420class CombinedAggFunc(AnonymousAggFunc):
4421    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4424class CombinedParameterizedAgg(ParameterizedAgg):
4425    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):
4430class Hll(AggFunc):
4431    arg_types = {"this": True, "expressions": False}
4432    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4435class ApproxDistinct(AggFunc):
4436    arg_types = {"this": True, "accuracy": False}
4437    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4440class Array(Func):
4441    arg_types = {"expressions": False}
4442    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4446class ToArray(Func):
4447    pass
key = 'toarray'
class ToChar(Func):
4452class ToChar(Func):
4453    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class Convert(Func):
4457class Convert(Func):
4458    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4461class GenerateSeries(Func):
4462    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4465class ArrayAgg(AggFunc):
4466    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4469class ArrayUniqueAgg(AggFunc):
4470    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4473class ArrayAll(Func):
4474    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4478class ArrayAny(Func):
4479    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4482class ArrayConcat(Func):
4483    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4484    arg_types = {"this": True, "expressions": False}
4485    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4488class ArrayContains(Binary, Func):
4489    pass
key = 'arraycontains'
class ArrayContained(Binary):
4492class ArrayContained(Binary):
4493    pass
key = 'arraycontained'
class ArrayFilter(Func):
4496class ArrayFilter(Func):
4497    arg_types = {"this": True, "expression": True}
4498    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4501class ArrayJoin(Func):
4502    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4505class ArrayOverlaps(Binary, Func):
4506    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4509class ArraySize(Func):
4510    arg_types = {"this": True, "expression": False}
4511    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4514class ArraySort(Func):
4515    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4518class ArraySum(Func):
4519    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4522class ArrayUnionAgg(AggFunc):
4523    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4526class Avg(AggFunc):
4527    pass
key = 'avg'
class AnyValue(AggFunc):
4530class AnyValue(AggFunc):
4531    pass
key = 'anyvalue'
class Lag(AggFunc):
4534class Lag(AggFunc):
4535    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4538class Lead(AggFunc):
4539    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4544class First(AggFunc):
4545    pass
key = 'first'
class Last(AggFunc):
4548class Last(AggFunc):
4549    pass
key = 'last'
class FirstValue(AggFunc):
4552class FirstValue(AggFunc):
4553    pass
key = 'firstvalue'
class LastValue(AggFunc):
4556class LastValue(AggFunc):
4557    pass
key = 'lastvalue'
class NthValue(AggFunc):
4560class NthValue(AggFunc):
4561    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4564class Case(Func):
4565    arg_types = {"this": False, "ifs": True, "default": False}
4566
4567    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4568        instance = maybe_copy(self, copy)
4569        instance.append(
4570            "ifs",
4571            If(
4572                this=maybe_parse(condition, copy=copy, **opts),
4573                true=maybe_parse(then, copy=copy, **opts),
4574            ),
4575        )
4576        return instance
4577
4578    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4579        instance = maybe_copy(self, copy)
4580        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4581        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:
4567    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4568        instance = maybe_copy(self, copy)
4569        instance.append(
4570            "ifs",
4571            If(
4572                this=maybe_parse(condition, copy=copy, **opts),
4573                true=maybe_parse(then, copy=copy, **opts),
4574            ),
4575        )
4576        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4578    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4579        instance = maybe_copy(self, copy)
4580        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4581        return instance
key = 'case'
class Cast(Func):
4584class Cast(Func):
4585    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4586
4587    @property
4588    def name(self) -> str:
4589        return self.this.name
4590
4591    @property
4592    def to(self) -> DataType:
4593        return self.args["to"]
4594
4595    @property
4596    def output_name(self) -> str:
4597        return self.name
4598
4599    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4600        """
4601        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4602        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4603        array<int> != array<float>.
4604
4605        Args:
4606            dtypes: the data types to compare this Cast's DataType to.
4607
4608        Returns:
4609            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4610        """
4611        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4587    @property
4588    def name(self) -> str:
4589        return self.this.name
to: DataType
4591    @property
4592    def to(self) -> DataType:
4593        return self.args["to"]
output_name: str
4595    @property
4596    def output_name(self) -> str:
4597        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:
4599    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4600        """
4601        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4602        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4603        array<int> != array<float>.
4604
4605        Args:
4606            dtypes: the data types to compare this Cast's DataType to.
4607
4608        Returns:
4609            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4610        """
4611        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):
4614class TryCast(Cast):
4615    pass
key = 'trycast'
class CastToStrType(Func):
4618class CastToStrType(Func):
4619    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4622class Collate(Binary, Func):
4623    pass
key = 'collate'
class Ceil(Func):
4626class Ceil(Func):
4627    arg_types = {"this": True, "decimals": False}
4628    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4631class Coalesce(Func):
4632    arg_types = {"this": True, "expressions": False}
4633    is_var_len_args = True
4634    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4637class Chr(Func):
4638    arg_types = {"this": True, "charset": False, "expressions": False}
4639    is_var_len_args = True
4640    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4643class Concat(Func):
4644    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4645    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4648class ConcatWs(Concat):
4649    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4653class ConnectByRoot(Func):
4654    pass
key = 'connectbyroot'
class Count(AggFunc):
4657class Count(AggFunc):
4658    arg_types = {"this": False, "expressions": False}
4659    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4662class CountIf(AggFunc):
4663    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4667class Cbrt(Func):
4668    pass
key = 'cbrt'
class CurrentDate(Func):
4671class CurrentDate(Func):
4672    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4675class CurrentDatetime(Func):
4676    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4679class CurrentTime(Func):
4680    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4683class CurrentTimestamp(Func):
4684    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4687class CurrentUser(Func):
4688    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4691class DateAdd(Func, IntervalOp):
4692    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4695class DateSub(Func, IntervalOp):
4696    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4699class DateDiff(Func, TimeUnit):
4700    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4701    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4704class DateTrunc(Func):
4705    arg_types = {"unit": True, "this": True, "zone": False}
4706
4707    def __init__(self, **args):
4708        unit = args.get("unit")
4709        if isinstance(unit, TimeUnit.VAR_LIKE):
4710            args["unit"] = Literal.string(
4711                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4712            )
4713        elif isinstance(unit, Week):
4714            unit.set("this", Literal.string(unit.this.name.upper()))
4715
4716        super().__init__(**args)
4717
4718    @property
4719    def unit(self) -> Expression:
4720        return self.args["unit"]
DateTrunc(**args)
4707    def __init__(self, **args):
4708        unit = args.get("unit")
4709        if isinstance(unit, TimeUnit.VAR_LIKE):
4710            args["unit"] = Literal.string(
4711                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4712            )
4713        elif isinstance(unit, Week):
4714            unit.set("this", Literal.string(unit.this.name.upper()))
4715
4716        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4718    @property
4719    def unit(self) -> Expression:
4720        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4723class DatetimeAdd(Func, IntervalOp):
4724    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4727class DatetimeSub(Func, IntervalOp):
4728    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4731class DatetimeDiff(Func, TimeUnit):
4732    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4735class DatetimeTrunc(Func, TimeUnit):
4736    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4739class DayOfWeek(Func):
4740    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4743class DayOfMonth(Func):
4744    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4747class DayOfYear(Func):
4748    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4751class ToDays(Func):
4752    pass
key = 'todays'
class WeekOfYear(Func):
4755class WeekOfYear(Func):
4756    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4759class MonthsBetween(Func):
4760    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4763class LastDay(Func, TimeUnit):
4764    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4765    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4768class Extract(Func):
4769    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4772class Timestamp(Func):
4773    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4776class TimestampAdd(Func, TimeUnit):
4777    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4780class TimestampSub(Func, TimeUnit):
4781    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4784class TimestampDiff(Func, TimeUnit):
4785    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4786    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4789class TimestampTrunc(Func, TimeUnit):
4790    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4793class TimeAdd(Func, TimeUnit):
4794    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4797class TimeSub(Func, TimeUnit):
4798    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4801class TimeDiff(Func, TimeUnit):
4802    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4805class TimeTrunc(Func, TimeUnit):
4806    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4809class DateFromParts(Func):
4810    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4811    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4814class TimeFromParts(Func):
4815    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4816    arg_types = {
4817        "hour": True,
4818        "min": True,
4819        "sec": True,
4820        "nano": False,
4821        "fractions": False,
4822        "precision": False,
4823    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4826class DateStrToDate(Func):
4827    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4830class DateToDateStr(Func):
4831    pass
key = 'datetodatestr'
class DateToDi(Func):
4834class DateToDi(Func):
4835    pass
key = 'datetodi'
class Date(Func):
4839class Date(Func):
4840    arg_types = {"this": False, "zone": False, "expressions": False}
4841    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4844class Day(Func):
4845    pass
key = 'day'
class Decode(Func):
4848class Decode(Func):
4849    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4852class DiToDate(Func):
4853    pass
key = 'ditodate'
class Encode(Func):
4856class Encode(Func):
4857    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4860class Exp(Func):
4861    pass
key = 'exp'
class Explode(Func):
4865class Explode(Func):
4866    arg_types = {"this": True, "expressions": False}
4867    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4870class ExplodeOuter(Explode):
4871    pass
key = 'explodeouter'
class Posexplode(Explode):
4874class Posexplode(Explode):
4875    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4878class PosexplodeOuter(Posexplode, ExplodeOuter):
4879    pass
key = 'posexplodeouter'
class Floor(Func):
4882class Floor(Func):
4883    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4886class FromBase64(Func):
4887    pass
key = 'frombase64'
class ToBase64(Func):
4890class ToBase64(Func):
4891    pass
key = 'tobase64'
class Greatest(Func):
4894class Greatest(Func):
4895    arg_types = {"this": True, "expressions": False}
4896    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4899class GroupConcat(AggFunc):
4900    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4903class Hex(Func):
4904    pass
key = 'hex'
class Xor(Connector, Func):
4907class Xor(Connector, Func):
4908    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4911class If(Func):
4912    arg_types = {"this": True, "true": True, "false": False}
4913    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4916class Nullif(Func):
4917    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4920class Initcap(Func):
4921    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4924class IsNan(Func):
4925    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4928class IsInf(Func):
4929    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4932class JSONPath(Expression):
4933    arg_types = {"expressions": True}
4934
4935    @property
4936    def output_name(self) -> str:
4937        last_segment = self.expressions[-1].this
4938        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4935    @property
4936    def output_name(self) -> str:
4937        last_segment = self.expressions[-1].this
4938        return last_segment if isinstance(last_segment, str) else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonpath'
class JSONPathPart(Expression):
4941class JSONPathPart(Expression):
4942    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4945class JSONPathFilter(JSONPathPart):
4946    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4949class JSONPathKey(JSONPathPart):
4950    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4953class JSONPathRecursive(JSONPathPart):
4954    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4957class JSONPathRoot(JSONPathPart):
4958    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4961class JSONPathScript(JSONPathPart):
4962    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4965class JSONPathSlice(JSONPathPart):
4966    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4969class JSONPathSelector(JSONPathPart):
4970    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4973class JSONPathSubscript(JSONPathPart):
4974    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4977class JSONPathUnion(JSONPathPart):
4978    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4981class JSONPathWildcard(JSONPathPart):
4982    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4985class FormatJson(Expression):
4986    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4989class JSONKeyValue(Expression):
4990    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4993class JSONObject(Func):
4994    arg_types = {
4995        "expressions": False,
4996        "null_handling": False,
4997        "unique_keys": False,
4998        "return_type": False,
4999        "encoding": False,
5000    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5003class JSONObjectAgg(AggFunc):
5004    arg_types = {
5005        "expressions": False,
5006        "null_handling": False,
5007        "unique_keys": False,
5008        "return_type": False,
5009        "encoding": False,
5010    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5014class JSONArray(Func):
5015    arg_types = {
5016        "expressions": True,
5017        "null_handling": False,
5018        "return_type": False,
5019        "strict": False,
5020    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5024class JSONArrayAgg(Func):
5025    arg_types = {
5026        "this": True,
5027        "order": False,
5028        "null_handling": False,
5029        "return_type": False,
5030        "strict": False,
5031    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5036class JSONColumnDef(Expression):
5037    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):
5040class JSONSchema(Expression):
5041    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5045class JSONTable(Func):
5046    arg_types = {
5047        "this": True,
5048        "schema": True,
5049        "path": False,
5050        "error_handling": False,
5051        "empty_handling": False,
5052    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5055class OpenJSONColumnDef(Expression):
5056    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):
5059class OpenJSON(Func):
5060    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5063class JSONBContains(Binary):
5064    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5067class JSONExtract(Binary, Func):
5068    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5069    _sql_names = ["JSON_EXTRACT"]
5070    is_var_len_args = True
5071
5072    @property
5073    def output_name(self) -> str:
5074        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5072    @property
5073    def output_name(self) -> str:
5074        return self.expression.output_name if not self.expressions else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextract'
class JSONExtractScalar(Binary, Func):
5077class JSONExtractScalar(Binary, Func):
5078    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5079    _sql_names = ["JSON_EXTRACT_SCALAR"]
5080    is_var_len_args = True
5081
5082    @property
5083    def output_name(self) -> str:
5084        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5082    @property
5083    def output_name(self) -> str:
5084        return self.expression.output_name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
5087class JSONBExtract(Binary, Func):
5088    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5091class JSONBExtractScalar(Binary, Func):
5092    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5095class JSONFormat(Func):
5096    arg_types = {"this": False, "options": False}
5097    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5101class JSONArrayContains(Binary, Predicate, Func):
5102    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5105class ParseJSON(Func):
5106    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5107    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5108    arg_types = {"this": True, "expressions": False}
5109    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5112class Least(Func):
5113    arg_types = {"this": True, "expressions": False}
5114    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5117class Left(Func):
5118    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5125class Length(Func):
5126    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5129class Levenshtein(Func):
5130    arg_types = {
5131        "this": True,
5132        "expression": False,
5133        "ins_cost": False,
5134        "del_cost": False,
5135        "sub_cost": False,
5136    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5139class Ln(Func):
5140    pass
key = 'ln'
class Log(Func):
5143class Log(Func):
5144    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5147class Log2(Func):
5148    pass
key = 'log2'
class Log10(Func):
5151class Log10(Func):
5152    pass
key = 'log10'
class LogicalOr(AggFunc):
5155class LogicalOr(AggFunc):
5156    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5159class LogicalAnd(AggFunc):
5160    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5163class Lower(Func):
5164    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5167class Map(Func):
5168    arg_types = {"keys": False, "values": False}
5169
5170    @property
5171    def keys(self) -> t.List[Expression]:
5172        keys = self.args.get("keys")
5173        return keys.expressions if keys else []
5174
5175    @property
5176    def values(self) -> t.List[Expression]:
5177        values = self.args.get("values")
5178        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5170    @property
5171    def keys(self) -> t.List[Expression]:
5172        keys = self.args.get("keys")
5173        return keys.expressions if keys else []
values: List[Expression]
5175    @property
5176    def values(self) -> t.List[Expression]:
5177        values = self.args.get("values")
5178        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5181class MapFromEntries(Func):
5182    pass
key = 'mapfromentries'
class StarMap(Func):
5185class StarMap(Func):
5186    pass
key = 'starmap'
class VarMap(Func):
5189class VarMap(Func):
5190    arg_types = {"keys": True, "values": True}
5191    is_var_len_args = True
5192
5193    @property
5194    def keys(self) -> t.List[Expression]:
5195        return self.args["keys"].expressions
5196
5197    @property
5198    def values(self) -> t.List[Expression]:
5199        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5193    @property
5194    def keys(self) -> t.List[Expression]:
5195        return self.args["keys"].expressions
values: List[Expression]
5197    @property
5198    def values(self) -> t.List[Expression]:
5199        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5203class MatchAgainst(Func):
5204    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5207class Max(AggFunc):
5208    arg_types = {"this": True, "expressions": False}
5209    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5212class MD5(Func):
5213    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5217class MD5Digest(Func):
5218    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5221class Min(AggFunc):
5222    arg_types = {"this": True, "expressions": False}
5223    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5226class Month(Func):
5227    pass
key = 'month'
class AddMonths(Func):
5230class AddMonths(Func):
5231    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5234class Nvl2(Func):
5235    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5239class Predict(Func):
5240    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5243class Pow(Binary, Func):
5244    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5247class PercentileCont(AggFunc):
5248    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5251class PercentileDisc(AggFunc):
5252    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5255class Quantile(AggFunc):
5256    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5259class ApproxQuantile(Quantile):
5260    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):
5263class Rand(Func):
5264    _sql_names = ["RAND", "RANDOM"]
5265    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5268class Randn(Func):
5269    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5272class RangeN(Func):
5273    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5276class ReadCSV(Func):
5277    _sql_names = ["READ_CSV"]
5278    is_var_len_args = True
5279    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5282class Reduce(Func):
5283    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):
5286class RegexpExtract(Func):
5287    arg_types = {
5288        "this": True,
5289        "expression": True,
5290        "position": False,
5291        "occurrence": False,
5292        "parameters": False,
5293        "group": False,
5294    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5297class RegexpReplace(Func):
5298    arg_types = {
5299        "this": True,
5300        "expression": True,
5301        "replacement": False,
5302        "position": False,
5303        "occurrence": False,
5304        "parameters": False,
5305        "modifiers": False,
5306    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5309class RegexpLike(Binary, Func):
5310    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5313class RegexpILike(Binary, Func):
5314    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5319class RegexpSplit(Func):
5320    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5323class Repeat(Func):
5324    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5329class Round(Func):
5330    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5333class RowNumber(Func):
5334    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5337class SafeDivide(Func):
5338    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5341class SHA(Func):
5342    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5345class SHA2(Func):
5346    _sql_names = ["SHA2"]
5347    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5350class Sign(Func):
5351    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5354class SortArray(Func):
5355    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5358class Split(Func):
5359    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5364class Substring(Func):
5365    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5368class StandardHash(Func):
5369    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5372class StartsWith(Func):
5373    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5374    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5377class StrPosition(Func):
5378    arg_types = {
5379        "this": True,
5380        "substr": True,
5381        "position": False,
5382        "instance": False,
5383    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5386class StrToDate(Func):
5387    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5390class StrToTime(Func):
5391    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5396class StrToUnix(Func):
5397    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5402class StrToMap(Func):
5403    arg_types = {
5404        "this": True,
5405        "pair_delim": False,
5406        "key_value_delim": False,
5407        "duplicate_resolution_callback": False,
5408    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5411class NumberToStr(Func):
5412    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5415class FromBase(Func):
5416    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5419class Struct(Func):
5420    arg_types = {"expressions": False}
5421    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5424class StructExtract(Func):
5425    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5430class Stuff(Func):
5431    _sql_names = ["STUFF", "INSERT"]
5432    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):
5435class Sum(AggFunc):
5436    pass
key = 'sum'
class Sqrt(Func):
5439class Sqrt(Func):
5440    pass
key = 'sqrt'
class Stddev(AggFunc):
5443class Stddev(AggFunc):
5444    pass
key = 'stddev'
class StddevPop(AggFunc):
5447class StddevPop(AggFunc):
5448    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5451class StddevSamp(AggFunc):
5452    pass
key = 'stddevsamp'
class TimeToStr(Func):
5455class TimeToStr(Func):
5456    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5459class TimeToTimeStr(Func):
5460    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5463class TimeToUnix(Func):
5464    pass
key = 'timetounix'
class TimeStrToDate(Func):
5467class TimeStrToDate(Func):
5468    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5471class TimeStrToTime(Func):
5472    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5475class TimeStrToUnix(Func):
5476    pass
key = 'timestrtounix'
class Trim(Func):
5479class Trim(Func):
5480    arg_types = {
5481        "this": True,
5482        "expression": False,
5483        "position": False,
5484        "collation": False,
5485    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5488class TsOrDsAdd(Func, TimeUnit):
5489    # return_type is used to correctly cast the arguments of this expression when transpiling it
5490    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5491
5492    @property
5493    def return_type(self) -> DataType:
5494        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
5492    @property
5493    def return_type(self) -> DataType:
5494        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5497class TsOrDsDiff(Func, TimeUnit):
5498    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5501class TsOrDsToDateStr(Func):
5502    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5505class TsOrDsToDate(Func):
5506    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5509class TsOrDsToTime(Func):
5510    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5513class TsOrDiToDi(Func):
5514    pass
key = 'tsorditodi'
class Unhex(Func):
5517class Unhex(Func):
5518    pass
key = 'unhex'
class UnixDate(Func):
5522class UnixDate(Func):
5523    pass
key = 'unixdate'
class UnixToStr(Func):
5526class UnixToStr(Func):
5527    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5532class UnixToTime(Func):
5533    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5534
5535    SECONDS = Literal.number(0)
5536    DECIS = Literal.number(1)
5537    CENTIS = Literal.number(2)
5538    MILLIS = Literal.number(3)
5539    DECIMILLIS = Literal.number(4)
5540    CENTIMILLIS = Literal.number(5)
5541    MICROS = Literal.number(6)
5542    DECIMICROS = Literal.number(7)
5543    CENTIMICROS = Literal.number(8)
5544    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
5547class UnixToTimeStr(Func):
5548    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5551class TimestampFromParts(Func):
5552    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5553    arg_types = {
5554        "year": True,
5555        "month": True,
5556        "day": True,
5557        "hour": True,
5558        "min": True,
5559        "sec": True,
5560        "nano": False,
5561        "zone": False,
5562        "milli": False,
5563    }
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):
5566class Upper(Func):
5567    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5570class Variance(AggFunc):
5571    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5574class VariancePop(AggFunc):
5575    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5578class Week(Func):
5579    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5582class XMLTable(Func):
5583    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):
5586class Year(Func):
5587    pass
key = 'year'
class Use(Expression):
5590class Use(Expression):
5591    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5594class Merge(Expression):
5595    arg_types = {
5596        "this": True,
5597        "using": True,
5598        "on": True,
5599        "expressions": True,
5600        "with": False,
5601    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5604class When(Func):
5605    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):
5610class NextValueFor(Func):
5611    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class '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 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <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'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, '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'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5649def maybe_parse(
5650    sql_or_expression: ExpOrStr,
5651    *,
5652    into: t.Optional[IntoType] = None,
5653    dialect: DialectType = None,
5654    prefix: t.Optional[str] = None,
5655    copy: bool = False,
5656    **opts,
5657) -> Expression:
5658    """Gracefully handle a possible string or expression.
5659
5660    Example:
5661        >>> maybe_parse("1")
5662        Literal(this=1, is_string=False)
5663        >>> maybe_parse(to_identifier("x"))
5664        Identifier(this=x, quoted=False)
5665
5666    Args:
5667        sql_or_expression: the SQL code string or an expression
5668        into: the SQLGlot Expression to parse into
5669        dialect: the dialect used to parse the input expressions (in the case that an
5670            input expression is a SQL string).
5671        prefix: a string to prefix the sql with before it gets parsed
5672            (automatically includes a space)
5673        copy: whether to copy the expression.
5674        **opts: other options to use to parse the input expressions (again, in the case
5675            that an input expression is a SQL string).
5676
5677    Returns:
5678        Expression: the parsed or given expression.
5679    """
5680    if isinstance(sql_or_expression, Expression):
5681        if copy:
5682            return sql_or_expression.copy()
5683        return sql_or_expression
5684
5685    if sql_or_expression is None:
5686        raise ParseError("SQL cannot be None")
5687
5688    import sqlglot
5689
5690    sql = str(sql_or_expression)
5691    if prefix:
5692        sql = f"{prefix} {sql}"
5693
5694    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)

Gracefully handle a possible string or expression.

Example:
>>> maybe_parse("1")
Literal(this=1, is_string=False)
>>> maybe_parse(to_identifier("x"))
Identifier(this=x, quoted=False)
Arguments:
  • sql_or_expression: the SQL code string or an expression
  • into: the SQLGlot Expression to parse into
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • prefix: a string to prefix the sql with before it gets parsed (automatically includes a space)
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Expression: the parsed or given expression.

def maybe_copy(instance, copy=True):
5705def maybe_copy(instance, copy=True):
5706    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:
5920def union(
5921    left: ExpOrStr,
5922    right: ExpOrStr,
5923    distinct: bool = True,
5924    dialect: DialectType = None,
5925    copy: bool = True,
5926    **opts,
5927) -> Union:
5928    """
5929    Initializes a syntax tree from one UNION expression.
5930
5931    Example:
5932        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5933        'SELECT * FROM foo UNION SELECT * FROM bla'
5934
5935    Args:
5936        left: the SQL code string corresponding to the left-hand side.
5937            If an `Expression` instance is passed, it will be used as-is.
5938        right: the SQL code string corresponding to the right-hand side.
5939            If an `Expression` instance is passed, it will be used as-is.
5940        distinct: set the DISTINCT flag if and only if this is true.
5941        dialect: the dialect used to parse the input expression.
5942        copy: whether to copy the expression.
5943        opts: other options to use to parse the input expressions.
5944
5945    Returns:
5946        The new Union instance.
5947    """
5948    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5949    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5950
5951    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
5954def intersect(
5955    left: ExpOrStr,
5956    right: ExpOrStr,
5957    distinct: bool = True,
5958    dialect: DialectType = None,
5959    copy: bool = True,
5960    **opts,
5961) -> Intersect:
5962    """
5963    Initializes a syntax tree from one INTERSECT expression.
5964
5965    Example:
5966        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5967        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5968
5969    Args:
5970        left: the SQL code string corresponding to the left-hand side.
5971            If an `Expression` instance is passed, it will be used as-is.
5972        right: the SQL code string corresponding to the right-hand side.
5973            If an `Expression` instance is passed, it will be used as-is.
5974        distinct: set the DISTINCT flag if and only if this is true.
5975        dialect: the dialect used to parse the input expression.
5976        copy: whether to copy the expression.
5977        opts: other options to use to parse the input expressions.
5978
5979    Returns:
5980        The new Intersect instance.
5981    """
5982    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5983    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5984
5985    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
5988def except_(
5989    left: ExpOrStr,
5990    right: ExpOrStr,
5991    distinct: bool = True,
5992    dialect: DialectType = None,
5993    copy: bool = True,
5994    **opts,
5995) -> Except:
5996    """
5997    Initializes a syntax tree from one EXCEPT expression.
5998
5999    Example:
6000        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6001        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6002
6003    Args:
6004        left: the SQL code string corresponding to the left-hand side.
6005            If an `Expression` instance is passed, it will be used as-is.
6006        right: the SQL code string corresponding to the right-hand side.
6007            If an `Expression` instance is passed, it will be used as-is.
6008        distinct: set the DISTINCT flag if and only if this is true.
6009        dialect: the dialect used to parse the input expression.
6010        copy: whether to copy the expression.
6011        opts: other options to use to parse the input expressions.
6012
6013    Returns:
6014        The new Except instance.
6015    """
6016    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6017    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6018
6019    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6022def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6023    """
6024    Initializes a syntax tree from one or multiple SELECT expressions.
6025
6026    Example:
6027        >>> select("col1", "col2").from_("tbl").sql()
6028        'SELECT col1, col2 FROM tbl'
6029
6030    Args:
6031        *expressions: the SQL code string to parse as the expressions of a
6032            SELECT statement. If an Expression instance is passed, this is used as-is.
6033        dialect: the dialect used to parse the input expressions (in the case that an
6034            input expression is a SQL string).
6035        **opts: other options to use to parse the input expressions (again, in the case
6036            that an input expression is a SQL string).
6037
6038    Returns:
6039        Select: the syntax tree for the SELECT statement.
6040    """
6041    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:
6044def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6045    """
6046    Initializes a syntax tree from a FROM expression.
6047
6048    Example:
6049        >>> from_("tbl").select("col1", "col2").sql()
6050        'SELECT col1, col2 FROM tbl'
6051
6052    Args:
6053        *expression: the SQL code string to parse as the FROM expressions of a
6054            SELECT statement. If an Expression instance is passed, this is used as-is.
6055        dialect: the dialect used to parse the input expression (in the case that the
6056            input expression is a SQL string).
6057        **opts: other options to use to parse the input expressions (again, in the case
6058            that the input expression is a SQL string).
6059
6060    Returns:
6061        Select: the syntax tree for the SELECT statement.
6062    """
6063    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:
6066def update(
6067    table: str | Table,
6068    properties: dict,
6069    where: t.Optional[ExpOrStr] = None,
6070    from_: t.Optional[ExpOrStr] = None,
6071    dialect: DialectType = None,
6072    **opts,
6073) -> Update:
6074    """
6075    Creates an update statement.
6076
6077    Example:
6078        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6079        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6080
6081    Args:
6082        *properties: dictionary of properties to set which are
6083            auto converted to sql objects eg None -> NULL
6084        where: sql conditional parsed into a WHERE statement
6085        from_: sql statement parsed into a FROM statement
6086        dialect: the dialect used to parse the input expressions.
6087        **opts: other options to use to parse the input expressions.
6088
6089    Returns:
6090        Update: the syntax tree for the UPDATE statement.
6091    """
6092    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6093    update_expr.set(
6094        "expressions",
6095        [
6096            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6097            for k, v in properties.items()
6098        ],
6099    )
6100    if from_:
6101        update_expr.set(
6102            "from",
6103            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6104        )
6105    if isinstance(where, Condition):
6106        where = Where(this=where)
6107    if where:
6108        update_expr.set(
6109            "where",
6110            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6111        )
6112    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:
6115def delete(
6116    table: ExpOrStr,
6117    where: t.Optional[ExpOrStr] = None,
6118    returning: t.Optional[ExpOrStr] = None,
6119    dialect: DialectType = None,
6120    **opts,
6121) -> Delete:
6122    """
6123    Builds a delete statement.
6124
6125    Example:
6126        >>> delete("my_table", where="id > 1").sql()
6127        'DELETE FROM my_table WHERE id > 1'
6128
6129    Args:
6130        where: sql conditional parsed into a WHERE statement
6131        returning: sql conditional parsed into a RETURNING statement
6132        dialect: the dialect used to parse the input expressions.
6133        **opts: other options to use to parse the input expressions.
6134
6135    Returns:
6136        Delete: the syntax tree for the DELETE statement.
6137    """
6138    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6139    if where:
6140        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6141    if returning:
6142        delete_expr = t.cast(
6143            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6144        )
6145    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
6148def insert(
6149    expression: ExpOrStr,
6150    into: ExpOrStr,
6151    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6152    overwrite: t.Optional[bool] = None,
6153    returning: t.Optional[ExpOrStr] = None,
6154    dialect: DialectType = None,
6155    copy: bool = True,
6156    **opts,
6157) -> Insert:
6158    """
6159    Builds an INSERT statement.
6160
6161    Example:
6162        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6163        'INSERT INTO tbl VALUES (1, 2, 3)'
6164
6165    Args:
6166        expression: the sql string or expression of the INSERT statement
6167        into: the tbl to insert data to.
6168        columns: optionally the table's column names.
6169        overwrite: whether to INSERT OVERWRITE or not.
6170        returning: sql conditional parsed into a RETURNING statement
6171        dialect: the dialect used to parse the input expressions.
6172        copy: whether to copy the expression.
6173        **opts: other options to use to parse the input expressions.
6174
6175    Returns:
6176        Insert: the syntax tree for the INSERT statement.
6177    """
6178    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6179    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6180
6181    if columns:
6182        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6183
6184    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6185
6186    if returning:
6187        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6188
6189    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6192def condition(
6193    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6194) -> Condition:
6195    """
6196    Initialize a logical condition expression.
6197
6198    Example:
6199        >>> condition("x=1").sql()
6200        'x = 1'
6201
6202        This is helpful for composing larger logical syntax trees:
6203        >>> where = condition("x=1")
6204        >>> where = where.and_("y=1")
6205        >>> Select().from_("tbl").select("*").where(where).sql()
6206        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6207
6208    Args:
6209        *expression: the SQL code string to parse.
6210            If an Expression instance is passed, this is used as-is.
6211        dialect: the dialect used to parse the input expression (in the case that the
6212            input expression is a SQL string).
6213        copy: Whether to copy `expression` (only applies to expressions).
6214        **opts: other options to use to parse the input expressions (again, in the case
6215            that the input expression is a SQL string).
6216
6217    Returns:
6218        The new Condition instance
6219    """
6220    return maybe_parse(
6221        expression,
6222        into=Condition,
6223        dialect=dialect,
6224        copy=copy,
6225        **opts,
6226    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6229def and_(
6230    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6231) -> Condition:
6232    """
6233    Combine multiple conditions with an AND logical operator.
6234
6235    Example:
6236        >>> and_("x=1", and_("y=1", "z=1")).sql()
6237        'x = 1 AND (y = 1 AND z = 1)'
6238
6239    Args:
6240        *expressions: the SQL code strings to parse.
6241            If an Expression instance is passed, this is used as-is.
6242        dialect: the dialect used to parse the input expression.
6243        copy: whether to copy `expressions` (only applies to Expressions).
6244        **opts: other options to use to parse the input expressions.
6245
6246    Returns:
6247        And: the new condition
6248    """
6249    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

And: the new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6252def or_(
6253    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6254) -> Condition:
6255    """
6256    Combine multiple conditions with an OR logical operator.
6257
6258    Example:
6259        >>> or_("x=1", or_("y=1", "z=1")).sql()
6260        'x = 1 OR (y = 1 OR z = 1)'
6261
6262    Args:
6263        *expressions: the SQL code strings to parse.
6264            If an Expression instance is passed, this is used as-is.
6265        dialect: the dialect used to parse the input expression.
6266        copy: whether to copy `expressions` (only applies to Expressions).
6267        **opts: other options to use to parse the input expressions.
6268
6269    Returns:
6270        Or: the new condition
6271    """
6272    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

Or: the new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
6275def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6276    """
6277    Wrap a condition with a NOT operator.
6278
6279    Example:
6280        >>> not_("this_suit='black'").sql()
6281        "NOT this_suit = 'black'"
6282
6283    Args:
6284        expression: the SQL code string to parse.
6285            If an Expression instance is passed, this is used as-is.
6286        dialect: the dialect used to parse the input expression.
6287        copy: whether to copy the expression or not.
6288        **opts: other options to use to parse the input expressions.
6289
6290    Returns:
6291        The new condition.
6292    """
6293    this = condition(
6294        expression,
6295        dialect=dialect,
6296        copy=copy,
6297        **opts,
6298    )
6299    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:
6302def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6303    """
6304    Wrap an expression in parentheses.
6305
6306    Example:
6307        >>> paren("5 + 3").sql()
6308        '(5 + 3)'
6309
6310    Args:
6311        expression: the SQL code string to parse.
6312            If an Expression instance is passed, this is used as-is.
6313        copy: whether to copy the expression or not.
6314
6315    Returns:
6316        The wrapped expression.
6317    """
6318    return Paren(this=maybe_parse(expression, copy=copy))

Wrap an expression in parentheses.

Example:
>>> paren("5 + 3").sql()
'(5 + 3)'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • copy: whether to copy the expression or not.
Returns:

The wrapped expression.

SAFE_IDENTIFIER_RE: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6334def to_identifier(name, quoted=None, copy=True):
6335    """Builds an identifier.
6336
6337    Args:
6338        name: The name to turn into an identifier.
6339        quoted: Whether to force quote the identifier.
6340        copy: Whether to copy name if it's an Identifier.
6341
6342    Returns:
6343        The identifier ast node.
6344    """
6345
6346    if name is None:
6347        return None
6348
6349    if isinstance(name, Identifier):
6350        identifier = maybe_copy(name, copy)
6351    elif isinstance(name, str):
6352        identifier = Identifier(
6353            this=name,
6354            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6355        )
6356    else:
6357        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6358    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6361def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6362    """
6363    Parses a given string into an identifier.
6364
6365    Args:
6366        name: The name to parse into an identifier.
6367        dialect: The dialect to parse against.
6368
6369    Returns:
6370        The identifier ast node.
6371    """
6372    try:
6373        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6374    except ParseError:
6375        expression = to_identifier(name)
6376
6377    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:
6383def to_interval(interval: str | Literal) -> Interval:
6384    """Builds an interval expression from a string like '1 day' or '5 months'."""
6385    if isinstance(interval, Literal):
6386        if not interval.is_string:
6387            raise ValueError("Invalid interval string.")
6388
6389        interval = interval.this
6390
6391    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6392
6393    if not interval_parts:
6394        raise ValueError("Invalid interval string.")
6395
6396    return Interval(
6397        this=Literal.string(interval_parts.group(1)),
6398        unit=Var(this=interval_parts.group(2).upper()),
6399    )

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]:
6410def to_table(
6411    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6412) -> t.Optional[Table]:
6413    """
6414    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6415    If a table is passed in then that table is returned.
6416
6417    Args:
6418        sql_path: a `[catalog].[schema].[table]` string.
6419        dialect: the source dialect according to which the table name will be parsed.
6420        copy: Whether to copy a table if it is passed in.
6421        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6422
6423    Returns:
6424        A table expression.
6425    """
6426    if sql_path is None or isinstance(sql_path, Table):
6427        return maybe_copy(sql_path, copy=copy)
6428    if not isinstance(sql_path, str):
6429        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6430
6431    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6432    if table:
6433        for k, v in kwargs.items():
6434            table.set(k, v)
6435
6436    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6439def to_column(sql_path: str | Column, **kwargs) -> Column:
6440    """
6441    Create a column from a `[table].[column]` sql path. Schema is optional.
6442
6443    If a column is passed in then that column is returned.
6444
6445    Args:
6446        sql_path: `[table].[column]` string
6447    Returns:
6448        Table: A column expression
6449    """
6450    if sql_path is None or isinstance(sql_path, Column):
6451        return sql_path
6452    if not isinstance(sql_path, str):
6453        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6454    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

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

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

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

Table: A column expression

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6457def alias_(
6458    expression: ExpOrStr,
6459    alias: t.Optional[str | Identifier],
6460    table: bool | t.Sequence[str | Identifier] = False,
6461    quoted: t.Optional[bool] = None,
6462    dialect: DialectType = None,
6463    copy: bool = True,
6464    **opts,
6465):
6466    """Create an Alias expression.
6467
6468    Example:
6469        >>> alias_('foo', 'bar').sql()
6470        'foo AS bar'
6471
6472        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6473        '(SELECT 1, 2) AS bar(a, b)'
6474
6475    Args:
6476        expression: the SQL code strings to parse.
6477            If an Expression instance is passed, this is used as-is.
6478        alias: the alias name to use. If the name has
6479            special characters it is quoted.
6480        table: Whether to create a table alias, can also be a list of columns.
6481        quoted: whether to quote the alias
6482        dialect: the dialect used to parse the input expression.
6483        copy: Whether to copy the expression.
6484        **opts: other options to use to parse the input expressions.
6485
6486    Returns:
6487        Alias: the aliased expression
6488    """
6489    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6490    alias = to_identifier(alias, quoted=quoted)
6491
6492    if table:
6493        table_alias = TableAlias(this=alias)
6494        exp.set("alias", table_alias)
6495
6496        if not isinstance(table, bool):
6497            for column in table:
6498                table_alias.append("columns", to_identifier(column, quoted=quoted))
6499
6500        return exp
6501
6502    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6503    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6504    # for the complete Window expression.
6505    #
6506    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6507
6508    if "alias" in exp.arg_types and not isinstance(exp, Window):
6509        exp.set("alias", alias)
6510        return exp
6511    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
6514def subquery(
6515    expression: ExpOrStr,
6516    alias: t.Optional[Identifier | str] = None,
6517    dialect: DialectType = None,
6518    **opts,
6519) -> Select:
6520    """
6521    Build a subquery expression.
6522
6523    Example:
6524        >>> subquery('select x from tbl', 'bar').select('x').sql()
6525        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6526
6527    Args:
6528        expression: the SQL code strings to parse.
6529            If an Expression instance is passed, this is used as-is.
6530        alias: the alias name to use.
6531        dialect: the dialect used to parse the input expression.
6532        **opts: other options to use to parse the input expressions.
6533
6534    Returns:
6535        A new Select instance with the subquery expression included.
6536    """
6537
6538    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6539    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):
6570def column(
6571    col,
6572    table=None,
6573    db=None,
6574    catalog=None,
6575    *,
6576    fields=None,
6577    quoted=None,
6578    copy=True,
6579):
6580    """
6581    Build a Column.
6582
6583    Args:
6584        col: Column name.
6585        table: Table name.
6586        db: Database name.
6587        catalog: Catalog name.
6588        fields: Additional fields using dots.
6589        quoted: Whether to force quotes on the column's identifiers.
6590        copy: Whether to copy identifiers if passed in.
6591
6592    Returns:
6593        The new Column instance.
6594    """
6595    this = Column(
6596        this=to_identifier(col, quoted=quoted, copy=copy),
6597        table=to_identifier(table, quoted=quoted, copy=copy),
6598        db=to_identifier(db, quoted=quoted, copy=copy),
6599        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6600    )
6601
6602    if fields:
6603        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6604    return this

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
6607def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6608    """Cast an expression to a data type.
6609
6610    Example:
6611        >>> cast('x + 1', 'int').sql()
6612        'CAST(x + 1 AS INT)'
6613
6614    Args:
6615        expression: The expression to cast.
6616        to: The datatype to cast to.
6617        copy: Whether to copy the supplied expressions.
6618
6619    Returns:
6620        The new Cast instance.
6621    """
6622    expression = maybe_parse(expression, copy=copy, **opts)
6623    data_type = DataType.build(to, copy=copy, **opts)
6624    expression = Cast(this=expression, to=data_type)
6625    expression.type = data_type
6626    return expression

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
6629def table_(
6630    table: Identifier | str,
6631    db: t.Optional[Identifier | str] = None,
6632    catalog: t.Optional[Identifier | str] = None,
6633    quoted: t.Optional[bool] = None,
6634    alias: t.Optional[Identifier | str] = None,
6635) -> Table:
6636    """Build a Table.
6637
6638    Args:
6639        table: Table name.
6640        db: Database name.
6641        catalog: Catalog name.
6642        quote: Whether to force quotes on the table's identifiers.
6643        alias: Table's alias.
6644
6645    Returns:
6646        The new Table instance.
6647    """
6648    return Table(
6649        this=to_identifier(table, quoted=quoted) if table else None,
6650        db=to_identifier(db, quoted=quoted) if db else None,
6651        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6652        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6653    )

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:
6656def values(
6657    values: t.Iterable[t.Tuple[t.Any, ...]],
6658    alias: t.Optional[str] = None,
6659    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6660) -> Values:
6661    """Build VALUES statement.
6662
6663    Example:
6664        >>> values([(1, '2')]).sql()
6665        "VALUES (1, '2')"
6666
6667    Args:
6668        values: values statements that will be converted to SQL
6669        alias: optional alias
6670        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6671         If either are provided then an alias is also required.
6672
6673    Returns:
6674        Values: the Values expression object
6675    """
6676    if columns and not alias:
6677        raise ValueError("Alias is required when providing columns")
6678
6679    return Values(
6680        expressions=[convert(tup) for tup in values],
6681        alias=(
6682            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6683            if columns
6684            else (TableAlias(this=to_identifier(alias)) if alias else None)
6685        ),
6686    )

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:
6689def var(name: t.Optional[ExpOrStr]) -> Var:
6690    """Build a SQL variable.
6691
6692    Example:
6693        >>> repr(var('x'))
6694        'Var(this=x)'
6695
6696        >>> repr(var(column('x', table='y')))
6697        'Var(this=x)'
6698
6699    Args:
6700        name: The name of the var or an expression who's name will become the var.
6701
6702    Returns:
6703        The new variable node.
6704    """
6705    if not name:
6706        raise ValueError("Cannot convert empty name into var.")
6707
6708    if isinstance(name, Expression):
6709        name = name.name
6710    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:
6713def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6714    """Build ALTER TABLE... RENAME... expression
6715
6716    Args:
6717        old_name: The old name of the table
6718        new_name: The new name of the table
6719
6720    Returns:
6721        Alter table expression
6722    """
6723    old_table = to_table(old_name)
6724    new_table = to_table(new_name)
6725    return AlterTable(
6726        this=old_table,
6727        actions=[
6728            RenameTable(this=new_table),
6729        ],
6730    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None) -> AlterTable:
6733def rename_column(
6734    table_name: str | Table,
6735    old_column_name: str | Column,
6736    new_column_name: str | Column,
6737    exists: t.Optional[bool] = None,
6738) -> AlterTable:
6739    """Build ALTER TABLE... RENAME COLUMN... expression
6740
6741    Args:
6742        table_name: Name of the table
6743        old_column: The old name of the column
6744        new_column: The new name of the column
6745        exists: Whether to add the `IF EXISTS` clause
6746
6747    Returns:
6748        Alter table expression
6749    """
6750    table = to_table(table_name)
6751    old_column = to_column(old_column_name)
6752    new_column = to_column(new_column_name)
6753    return AlterTable(
6754        this=table,
6755        actions=[
6756            RenameColumn(this=old_column, to=new_column, exists=exists),
6757        ],
6758    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6761def convert(value: t.Any, copy: bool = False) -> Expression:
6762    """Convert a python value into an expression object.
6763
6764    Raises an error if a conversion is not possible.
6765
6766    Args:
6767        value: A python object.
6768        copy: Whether to copy `value` (only applies to Expressions and collections).
6769
6770    Returns:
6771        Expression: the equivalent expression object.
6772    """
6773    if isinstance(value, Expression):
6774        return maybe_copy(value, copy)
6775    if isinstance(value, str):
6776        return Literal.string(value)
6777    if isinstance(value, bool):
6778        return Boolean(this=value)
6779    if value is None or (isinstance(value, float) and math.isnan(value)):
6780        return null()
6781    if isinstance(value, numbers.Number):
6782        return Literal.number(value)
6783    if isinstance(value, datetime.datetime):
6784        datetime_literal = Literal.string(
6785            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6786        )
6787        return TimeStrToTime(this=datetime_literal)
6788    if isinstance(value, datetime.date):
6789        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6790        return DateStrToDate(this=date_literal)
6791    if isinstance(value, tuple):
6792        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6793    if isinstance(value, list):
6794        return Array(expressions=[convert(v, copy=copy) for v in value])
6795    if isinstance(value, dict):
6796        return Map(
6797            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6798            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6799        )
6800    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
6803def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6804    """
6805    Replace children of an expression with the result of a lambda fun(child) -> exp.
6806    """
6807    for k, v in expression.args.items():
6808        is_list_arg = type(v) is list
6809
6810        child_nodes = v if is_list_arg else [v]
6811        new_child_nodes = []
6812
6813        for cn in child_nodes:
6814            if isinstance(cn, Expression):
6815                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6816                    new_child_nodes.append(child_node)
6817                    child_node.parent = expression
6818                    child_node.arg_key = k
6819            else:
6820                new_child_nodes.append(cn)
6821
6822        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]:
6825def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6826    """
6827    Return all table names referenced through columns in an expression.
6828
6829    Example:
6830        >>> import sqlglot
6831        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6832        ['a', 'c']
6833
6834    Args:
6835        expression: expression to find table names.
6836        exclude: a table name to exclude
6837
6838    Returns:
6839        A list of unique names.
6840    """
6841    return {
6842        table
6843        for table in (column.table for column in expression.find_all(Column))
6844        if table and table != exclude
6845    }

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:
6848def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6849    """Get the full name of a table as a string.
6850
6851    Args:
6852        table: Table expression node or string.
6853        dialect: The dialect to generate the table name for.
6854        identify: Determines when an identifier should be quoted. Possible values are:
6855            False (default): Never quote, except in cases where it's mandatory by the dialect.
6856            True: Always quote.
6857
6858    Examples:
6859        >>> from sqlglot import exp, parse_one
6860        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6861        'a.b.c'
6862
6863    Returns:
6864        The table name.
6865    """
6866
6867    table = maybe_parse(table, into=Table, dialect=dialect)
6868
6869    if not table:
6870        raise ValueError(f"Cannot parse {table}")
6871
6872    return ".".join(
6873        (
6874            part.sql(dialect=dialect, identify=True, copy=False)
6875            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6876            else part.name
6877        )
6878        for part in table.parts
6879    )

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:
6882def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6883    """Returns a case normalized table name without quotes.
6884
6885    Args:
6886        table: the table to normalize
6887        dialect: the dialect to use for normalization rules
6888        copy: whether to copy the expression.
6889
6890    Examples:
6891        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6892        'A-B.c'
6893    """
6894    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6895
6896    return ".".join(
6897        p.name
6898        for p in normalize_identifiers(
6899            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6900        ).parts
6901    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
6904def replace_tables(
6905    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6906) -> E:
6907    """Replace all tables in expression according to the mapping.
6908
6909    Args:
6910        expression: expression node to be transformed and replaced.
6911        mapping: mapping of table names.
6912        dialect: the dialect of the mapping table
6913        copy: whether to copy the expression.
6914
6915    Examples:
6916        >>> from sqlglot import exp, parse_one
6917        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6918        'SELECT * FROM c /* a.b */'
6919
6920    Returns:
6921        The mapped expression.
6922    """
6923
6924    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6925
6926    def _replace_tables(node: Expression) -> Expression:
6927        if isinstance(node, Table):
6928            original = normalize_table_name(node, dialect=dialect)
6929            new_name = mapping.get(original)
6930
6931            if new_name:
6932                table = to_table(
6933                    new_name,
6934                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6935                    dialect=dialect,
6936                )
6937                table.add_comments([original])
6938                return table
6939        return node
6940
6941    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 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:
6944def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6945    """Replace placeholders in an expression.
6946
6947    Args:
6948        expression: expression node to be transformed and replaced.
6949        args: positional names that will substitute unnamed placeholders in the given order.
6950        kwargs: keyword arguments that will substitute named placeholders.
6951
6952    Examples:
6953        >>> from sqlglot import exp, parse_one
6954        >>> replace_placeholders(
6955        ...     parse_one("select * from :tbl where ? = ?"),
6956        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6957        ... ).sql()
6958        "SELECT * FROM foo WHERE str_col = 'b'"
6959
6960    Returns:
6961        The mapped expression.
6962    """
6963
6964    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6965        if isinstance(node, Placeholder):
6966            if node.name:
6967                new_name = kwargs.get(node.name)
6968                if new_name is not None:
6969                    return convert(new_name)
6970            else:
6971                try:
6972                    return convert(next(args))
6973                except StopIteration:
6974                    pass
6975        return node
6976
6977    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
6980def expand(
6981    expression: Expression,
6982    sources: t.Dict[str, Query],
6983    dialect: DialectType = None,
6984    copy: bool = True,
6985) -> Expression:
6986    """Transforms an expression by expanding all referenced sources into subqueries.
6987
6988    Examples:
6989        >>> from sqlglot import parse_one
6990        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6991        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6992
6993        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6994        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6995
6996    Args:
6997        expression: The expression to expand.
6998        sources: A dictionary of name to Queries.
6999        dialect: The dialect of the sources dict.
7000        copy: Whether to copy the expression during transformation. Defaults to True.
7001
7002    Returns:
7003        The transformed expression.
7004    """
7005    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7006
7007    def _expand(node: Expression):
7008        if isinstance(node, Table):
7009            name = normalize_table_name(node, dialect=dialect)
7010            source = sources.get(name)
7011            if source:
7012                subquery = source.subquery(node.alias or name)
7013                subquery.comments = [f"source: {name}"]
7014                return subquery.transform(_expand, copy=False)
7015        return node
7016
7017    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
7020def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7021    """
7022    Returns a Func expression.
7023
7024    Examples:
7025        >>> func("abs", 5).sql()
7026        'ABS(5)'
7027
7028        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7029        'CAST(5 AS DOUBLE)'
7030
7031    Args:
7032        name: the name of the function to build.
7033        args: the args used to instantiate the function of interest.
7034        copy: whether to copy the argument expressions.
7035        dialect: the source dialect.
7036        kwargs: the kwargs used to instantiate the function of interest.
7037
7038    Note:
7039        The arguments `args` and `kwargs` are mutually exclusive.
7040
7041    Returns:
7042        An instance of the function of interest, or an anonymous function, if `name` doesn't
7043        correspond to an existing `sqlglot.expressions.Func` class.
7044    """
7045    if args and kwargs:
7046        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7047
7048    from sqlglot.dialects.dialect import Dialect
7049
7050    dialect = Dialect.get_or_raise(dialect)
7051
7052    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7053    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7054
7055    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7056    if constructor:
7057        if converted:
7058            if "dialect" in constructor.__code__.co_varnames:
7059                function = constructor(converted, dialect=dialect)
7060            else:
7061                function = constructor(converted)
7062        elif constructor.__name__ == "from_arg_list":
7063            function = constructor.__self__(**kwargs)  # type: ignore
7064        else:
7065            constructor = FUNCTION_BY_NAME.get(name.upper())
7066            if constructor:
7067                function = constructor(**kwargs)
7068            else:
7069                raise ValueError(
7070                    f"Unable to convert '{name}' into a Func. Either manually construct "
7071                    "the Func expression of interest or parse the function call."
7072                )
7073    else:
7074        kwargs = kwargs or {"expressions": converted}
7075        function = Anonymous(this=name, **kwargs)
7076
7077    for error_message in function.error_messages(converted):
7078        raise ValueError(error_message)
7079
7080    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
7083def case(
7084    expression: t.Optional[ExpOrStr] = None,
7085    **opts,
7086) -> Case:
7087    """
7088    Initialize a CASE statement.
7089
7090    Example:
7091        case().when("a = 1", "foo").else_("bar")
7092
7093    Args:
7094        expression: Optionally, the input expression (not all dialects support this)
7095        **opts: Extra keyword arguments for parsing `expression`
7096    """
7097    if expression is not None:
7098        this = maybe_parse(expression, **opts)
7099    else:
7100        this = None
7101    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:
7104def cast_unless(
7105    expression: ExpOrStr,
7106    to: DATA_TYPE,
7107    *types: DATA_TYPE,
7108    **opts: t.Any,
7109) -> Expression | Cast:
7110    """
7111    Cast an expression to a data type unless it is a specified type.
7112
7113    Args:
7114        expression: The expression to cast.
7115        to: The data type to cast to.
7116        **types: The types to exclude from casting.
7117        **opts: Extra keyword arguments for parsing `expression`
7118    """
7119    expr = maybe_parse(expression, **opts)
7120    if expr.is_type(*types):
7121        return expr
7122    return cast(expr, to, **opts)

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

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7125def array(
7126    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7127) -> Array:
7128    """
7129    Returns an array.
7130
7131    Examples:
7132        >>> array(1, 'x').sql()
7133        'ARRAY(1, x)'
7134
7135    Args:
7136        expressions: the expressions to add to the array.
7137        copy: whether to copy the argument expressions.
7138        dialect: the source dialect.
7139        kwargs: the kwargs used to instantiate the function of interest.
7140
7141    Returns:
7142        An array expression.
7143    """
7144    return Array(
7145        expressions=[
7146            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7147            for expression in expressions
7148        ]
7149    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7152def tuple_(
7153    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7154) -> Tuple:
7155    """
7156    Returns an tuple.
7157
7158    Examples:
7159        >>> tuple_(1, 'x').sql()
7160        '(1, x)'
7161
7162    Args:
7163        expressions: the expressions to add to the tuple.
7164        copy: whether to copy the argument expressions.
7165        dialect: the source dialect.
7166        kwargs: the kwargs used to instantiate the function of interest.
7167
7168    Returns:
7169        A tuple expression.
7170    """
7171    return Tuple(
7172        expressions=[
7173            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7174            for expression in expressions
7175        ]
7176    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
7179def true() -> Boolean:
7180    """
7181    Returns a true Boolean expression.
7182    """
7183    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7186def false() -> Boolean:
7187    """
7188    Returns a false Boolean expression.
7189    """
7190    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7193def null() -> Null:
7194    """
7195    Returns a Null expression.
7196    """
7197    return Null()

Returns a Null expression.