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

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):
1883class OnConflict(Expression):
1884    arg_types = {
1885        "duplicate": False,
1886        "expressions": False,
1887        "nothing": False,
1888        "key": False,
1889        "constraint": False,
1890    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1893class Returning(Expression):
1894    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1898class Introducer(Expression):
1899    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1903class National(Expression):
1904    pass
key = 'national'
class LoadData(Expression):
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    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1919class Partition(Expression):
1920    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
1923class PartitionRange(Expression):
1924    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
1927class Fetch(Expression):
1928    arg_types = {
1929        "direction": False,
1930        "count": False,
1931        "percent": False,
1932        "with_ties": False,
1933    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
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    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1947class Lambda(Expression):
1948    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1951class Limit(Expression):
1952    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):
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
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1958    @property
1959    def hashable_args(self) -> t.Any:
1960        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1962    @classmethod
1963    def number(cls, number) -> Literal:
1964        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1966    @classmethod
1967    def string(cls, string) -> Literal:
1968        return cls(this=str(string), is_string=True)
output_name: str
1970    @property
1971    def output_name(self) -> str:
1972        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):
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
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1987    @property
1988    def method(self) -> str:
1989        return self.text("method").upper()
kind: str
1991    @property
1992    def kind(self) -> str:
1993        return self.text("kind").upper()
side: str
1995    @property
1996    def side(self) -> str:
1997        return self.text("side").upper()
hint: str
1999    @property
2000    def hint(self) -> str:
2001        return self.text("hint").upper()
alias_or_name: str
2003    @property
2004    def alias_or_name(self) -> str:
2005        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:
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

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

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):
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    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
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    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2120class Final(Expression):
2121    pass
key = 'final'
class Offset(Expression):
2124class Offset(Expression):
2125    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2128class Order(Expression):
2129    arg_types = {
2130        "this": False,
2131        "expressions": True,
2132        "interpolate": False,
2133        "siblings": False,
2134    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2138class WithFill(Expression):
2139    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2144class Cluster(Order):
2145    pass
key = 'cluster'
class Distribute(Order):
2148class Distribute(Order):
2149    pass
key = 'distribute'
class Sort(Order):
2152class Sort(Order):
2153    pass
key = 'sort'
class Ordered(Expression):
2156class Ordered(Expression):
2157    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):
2160class Property(Expression):
2161    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2164class AlgorithmProperty(Property):
2165    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2168class AutoIncrementProperty(Property):
2169    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2173class AutoRefreshProperty(Property):
2174    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2177class BlockCompressionProperty(Property):
2178    arg_types = {
2179        "autotemp": False,
2180        "always": False,
2181        "default": False,
2182        "manual": False,
2183        "never": False,
2184    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2187class CharacterSetProperty(Property):
2188    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2191class ChecksumProperty(Property):
2192    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2195class CollateProperty(Property):
2196    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2199class CopyGrantsProperty(Property):
2200    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2203class DataBlocksizeProperty(Property):
2204    arg_types = {
2205        "size": False,
2206        "units": False,
2207        "minimum": False,
2208        "maximum": False,
2209        "default": False,
2210    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2213class DefinerProperty(Property):
2214    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2217class DistKeyProperty(Property):
2218    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2221class DistStyleProperty(Property):
2222    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2225class EngineProperty(Property):
2226    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2229class HeapProperty(Property):
2230    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2233class ToTableProperty(Property):
2234    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2237class ExecuteAsProperty(Property):
2238    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2241class ExternalProperty(Property):
2242    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2245class FallbackProperty(Property):
2246    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2249class FileFormatProperty(Property):
2250    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2253class FreespaceProperty(Property):
2254    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InheritsProperty(Property):
2257class InheritsProperty(Property):
2258    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2261class InputModelProperty(Property):
2262    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2265class OutputModelProperty(Property):
2266    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
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    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2279class JournalProperty(Property):
2280    arg_types = {
2281        "no": False,
2282        "dual": False,
2283        "before": False,
2284        "local": False,
2285        "after": False,
2286    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2289class LanguageProperty(Property):
2290    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2294class ClusteredByProperty(Property):
2295    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2298class DictProperty(Property):
2299    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2302class DictSubProperty(Property):
2303    pass
key = 'dictsubproperty'
class DictRange(Property):
2306class DictRange(Property):
2307    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2312class OnCluster(Property):
2313    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2316class LikeProperty(Property):
2317    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2320class LocationProperty(Property):
2321    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2324class LockProperty(Property):
2325    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
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    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2338class LogProperty(Property):
2339    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2342class MaterializedProperty(Property):
2343    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2346class MergeBlockRatioProperty(Property):
2347    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):
2350class NoPrimaryIndexProperty(Property):
2351    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2354class OnProperty(Property):
2355    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2358class OnCommitProperty(Property):
2359    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2362class PartitionedByProperty(Property):
2363    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
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    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2377class PartitionedOfProperty(Property):
2378    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2379    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2382class RemoteWithConnectionModelProperty(Property):
2383    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2386class ReturnsProperty(Property):
2387    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2390class RowFormatProperty(Property):
2391    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
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    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2407class RowFormatSerdeProperty(Property):
2408    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
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    }
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):
2424class SampleProperty(Property):
2425    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2428class SchemaCommentProperty(Property):
2429    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2432class SerdeProperties(Property):
2433    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2436class SetProperty(Property):
2437    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SetConfigProperty(Property):
2440class SetConfigProperty(Property):
2441    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2444class SettingsProperty(Property):
2445    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2448class SortKeyProperty(Property):
2449    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2452class SqlReadWriteProperty(Property):
2453    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2456class SqlSecurityProperty(Property):
2457    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2460class StabilityProperty(Property):
2461    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2464class TemporaryProperty(Property):
2465    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2468class TransformModelProperty(Property):
2469    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2472class TransientProperty(Property):
2473    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2476class VolatileProperty(Property):
2477    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2480class WithDataProperty(Property):
2481    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2484class WithJournalTableProperty(Property):
2485    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2488class WithSystemVersioningProperty(Property):
2489    # this -> history table name, expression -> data consistency check
2490    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
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)
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:
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)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
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()

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):
2556class Qualify(Expression):
2557    pass
key = 'qualify'
class InputOutputFormat(Expression):
2560class InputOutputFormat(Expression):
2561    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2565class Return(Expression):
2566    pass
key = 'return'
class Reference(Expression):
2569class Reference(Expression):
2570    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
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        )
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:
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        )
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):
2629class QueryOption(Expression):
2630    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2634class WithTableHint(Expression):
2635    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2639class IndexTableHint(Expression):
2640    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2644class HistoricalData(Expression):
2645    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
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
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
2667    @property
2668    def name(self) -> str:
2669        if isinstance(self.this, Func):
2670            return ""
2671        return self.this.name
db: str
2673    @property
2674    def db(self) -> str:
2675        return self.text("db")
catalog: str
2677    @property
2678    def catalog(self) -> str:
2679        return self.text("catalog")
selects: List[Expression]
2681    @property
2682    def selects(self) -> t.List[Expression]:
2683        return []
named_selects: List[str]
2685    @property
2686    def named_selects(self) -> t.List[str]:
2687        return []
parts: List[Expression]
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

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
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
key = 'table'
class Union(Query):
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
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:
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

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]
2738    @property
2739    def named_selects(self) -> t.List[str]:
2740        return self.this.unnest().named_selects

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

left: Expression
2750    @property
2751    def left(self) -> Expression:
2752        return self.this
right: Expression
2754    @property
2755    def right(self) -> Expression:
2756        return self.expression
key = 'union'
class Except(Union):
2759class Except(Union):
2760    pass
key = 'except'
class Intersect(Union):
2763class Intersect(Union):
2764    pass
key = 'intersect'
class Unnest(UDTF):
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
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
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
key = 'unnest'
class Update(Expression):
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    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2796class Values(UDTF):
2797    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2800class Var(Expression):
2801    pass
key = 'var'
class Version(Expression):
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}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2818class Schema(Expression):
2819    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2824class Lock(Expression):
2825    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
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
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:
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        )

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

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

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

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

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

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

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

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

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

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

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

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:
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        )
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:
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        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
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

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

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

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

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

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
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
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):
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

Returns the first non subquery.

def unwrap(self) -> Subquery:
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
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:
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

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

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
3527    @property
3528    def is_star(self) -> bool:
3529        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3531    @property
3532    def output_name(self) -> str:
3533        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):
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    }
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):
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    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
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"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3576    @property
3577    def unpivot(self) -> bool:
3578        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
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    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3593class WindowSpec(Expression):
3594    arg_types = {
3595        "kind": False,
3596        "start": False,
3597        "start_side": False,
3598        "end": False,
3599        "end_side": False,
3600    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3603class PreWhere(Expression):
3604    pass
key = 'prewhere'
class Where(Expression):
3607class Where(Expression):
3608    pass
key = 'where'
class Star(Expression):
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
arg_types = {'except': False, 'replace': False}
name: str
3614    @property
3615    def name(self) -> str:
3616        return "*"
output_name: str
3618    @property
3619    def output_name(self) -> str:
3620        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):
3623class Parameter(Condition):
3624    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3627class SessionParameter(Condition):
3628    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3631class Placeholder(Condition):
3632    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3635class Null(Condition):
3636    arg_types: t.Dict[str, t.Any] = {}
3637
3638    @property
3639    def name(self) -> str:
3640        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3638    @property
3639    def name(self) -> str:
3640        return "NULL"
key = 'null'
class Boolean(Condition):
3643class Boolean(Condition):
3644    pass
key = 'boolean'
class DataTypeParam(Expression):
3647class DataTypeParam(Expression):
3648    arg_types = {"this": True, "expression": False}
3649
3650    @property
3651    def name(self) -> str:
3652        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3650    @property
3651    def name(self) -> str:
3652        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
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
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.BIT: 'BIT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
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})

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

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):
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()

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):
3889class PseudoType(DataType):
3890    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3894class ObjectIdentifier(DataType):
3895    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3899class SubqueryPredicate(Predicate):
3900    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3903class All(SubqueryPredicate):
3904    pass
key = 'all'
class Any(SubqueryPredicate):
3907class Any(SubqueryPredicate):
3908    pass
key = 'any'
class Exists(SubqueryPredicate):
3911class Exists(SubqueryPredicate):
3912    pass
key = 'exists'
class Command(Expression):
3917class Command(Expression):
3918    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3921class Transaction(Expression):
3922    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3925class Commit(Expression):
3926    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3929class Rollback(Expression):
3930    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3933class AlterTable(Expression):
3934    arg_types = {
3935        "this": True,
3936        "actions": True,
3937        "exists": False,
3938        "only": False,
3939        "options": False,
3940    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
3943class AddConstraint(Expression):
3944    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
3947class DropPartition(Expression):
3948    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
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
arg_types = {'this': True, 'expression': True}
left: Expression
3955    @property
3956    def left(self) -> Expression:
3957        return self.this
right: Expression
3959    @property
3960    def right(self) -> Expression:
3961        return self.expression
key = 'binary'
class Add(Binary):
3964class Add(Binary):
3965    pass
key = 'add'
class Connector(Binary):
3968class Connector(Binary):
3969    pass
key = 'connector'
class And(Connector):
3972class And(Connector):
3973    pass
key = 'and'
class Or(Connector):
3976class Or(Connector):
3977    pass
key = 'or'
class BitwiseAnd(Binary):
3980class BitwiseAnd(Binary):
3981    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3984class BitwiseLeftShift(Binary):
3985    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3988class BitwiseOr(Binary):
3989    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3992class BitwiseRightShift(Binary):
3993    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3996class BitwiseXor(Binary):
3997    pass
key = 'bitwisexor'
class Div(Binary):
4000class Div(Binary):
4001    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):
4004class Overlaps(Binary):
4005    pass
key = 'overlaps'
class Dot(Binary):
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
is_star: bool
4009    @property
4010    def is_star(self) -> bool:
4011        return self.expression.is_star

Checks whether an expression is a star.

name: str
4013    @property
4014    def name(self) -> str:
4015        return self.expression.name
output_name: str
4017    @property
4018    def output_name(self) -> str:
4019        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:
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))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
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

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

key = 'dot'
class DPipe(Binary):
4046class DPipe(Binary):
4047    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4050class EQ(Binary, Predicate):
4051    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4054class NullSafeEQ(Binary, Predicate):
4055    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4058class NullSafeNEQ(Binary, Predicate):
4059    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4063class PropertyEQ(Binary):
4064    pass
key = 'propertyeq'
class Distance(Binary):
4067class Distance(Binary):
4068    pass
key = 'distance'
class Escape(Binary):
4071class Escape(Binary):
4072    pass
key = 'escape'
class Glob(Binary, Predicate):
4075class Glob(Binary, Predicate):
4076    pass
key = 'glob'
class GT(Binary, Predicate):
4079class GT(Binary, Predicate):
4080    pass
key = 'gt'
class GTE(Binary, Predicate):
4083class GTE(Binary, Predicate):
4084    pass
key = 'gte'
class ILike(Binary, Predicate):
4087class ILike(Binary, Predicate):
4088    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4091class ILikeAny(Binary, Predicate):
4092    pass
key = 'ilikeany'
class IntDiv(Binary):
4095class IntDiv(Binary):
4096    pass
key = 'intdiv'
class Is(Binary, Predicate):
4099class Is(Binary, Predicate):
4100    pass
key = 'is'
class Kwarg(Binary):
4103class Kwarg(Binary):
4104    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4107class Like(Binary, Predicate):
4108    pass
key = 'like'
class LikeAny(Binary, Predicate):
4111class LikeAny(Binary, Predicate):
4112    pass
key = 'likeany'
class LT(Binary, Predicate):
4115class LT(Binary, Predicate):
4116    pass
key = 'lt'
class LTE(Binary, Predicate):
4119class LTE(Binary, Predicate):
4120    pass
key = 'lte'
class Mod(Binary):
4123class Mod(Binary):
4124    pass
key = 'mod'
class Mul(Binary):
4127class Mul(Binary):
4128    pass
key = 'mul'
class NEQ(Binary, Predicate):
4131class NEQ(Binary, Predicate):
4132    pass
key = 'neq'
class Operator(Binary):
4136class Operator(Binary):
4137    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4140class SimilarTo(Binary, Predicate):
4141    pass
key = 'similarto'
class Slice(Binary):
4144class Slice(Binary):
4145    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4148class Sub(Binary):
4149    pass
key = 'sub'
class Unary(Condition):
4154class Unary(Condition):
4155    pass
key = 'unary'
class BitwiseNot(Unary):
4158class BitwiseNot(Unary):
4159    pass
key = 'bitwisenot'
class Not(Unary):
4162class Not(Unary):
4163    pass
key = 'not'
class Paren(Unary):
4166class Paren(Unary):
4167    arg_types = {"this": True, "with": False}
4168
4169    @property
4170    def output_name(self) -> str:
4171        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4169    @property
4170    def output_name(self) -> str:
4171        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):
4174class Neg(Unary):
4175    pass
key = 'neg'
class Alias(Expression):
4178class Alias(Expression):
4179    arg_types = {"this": True, "alias": False}
4180
4181    @property
4182    def output_name(self) -> str:
4183        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4181    @property
4182    def output_name(self) -> str:
4183        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):
4188class PivotAlias(Alias):
4189    pass
key = 'pivotalias'
class Aliases(Expression):
4192class Aliases(Expression):
4193    arg_types = {"this": True, "expressions": True}
4194
4195    @property
4196    def aliases(self):
4197        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4195    @property
4196    def aliases(self):
4197        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4201class AtIndex(Expression):
4202    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4205class AtTimeZone(Expression):
4206    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4209class FromTimeZone(Expression):
4210    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4213class Between(Predicate):
4214    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
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
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
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

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):
4229class Distinct(Expression):
4230    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
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    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4245class ForIn(Expression):
4246    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
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")

Automatically converts unit arg into a var.

TimeUnit(**args)
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)
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]
4280    @property
4281    def unit(self) -> t.Optional[Var]:
4282        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
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        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4288    def interval(self):
4289        return Interval(
4290            this=self.expression.copy(),
4291            unit=self.unit.copy(),
4292        )
key = 'intervalop'
class IntervalSpan(DataType):
4298class IntervalSpan(DataType):
4299    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4302class Interval(TimeUnit):
4303    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4306class IgnoreNulls(Expression):
4307    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4310class RespectNulls(Expression):
4311    pass
key = 'respectnulls'
class HavingMax(Expression):
4315class HavingMax(Expression):
4316    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
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()}

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):
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)
@classmethod
def sql_names(cls):
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
@classmethod
def sql_name(cls):
4360    @classmethod
4361    def sql_name(cls):
4362        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4364    @classmethod
4365    def default_parser_mappings(cls):
4366        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4369class AggFunc(Func):
4370    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4373class ParameterizedAgg(AggFunc):
4374    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4377class Abs(Func):
4378    pass
key = 'abs'
class ArgMax(AggFunc):
4381class ArgMax(AggFunc):
4382    arg_types = {"this": True, "expression": True, "count": False}
4383    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4386class ArgMin(AggFunc):
4387    arg_types = {"this": True, "expression": True, "count": False}
4388    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4391class ApproxTopK(AggFunc):
4392    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4395class Flatten(Func):
4396    pass
key = 'flatten'
class Transform(Func):
4400class Transform(Func):
4401    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
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
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4408    @property
4409    def name(self) -> str:
4410        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4413class AnonymousAggFunc(AggFunc):
4414    arg_types = {"this": True, "expressions": False}
4415    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4419class CombinedAggFunc(AnonymousAggFunc):
4420    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4423class CombinedParameterizedAgg(ParameterizedAgg):
4424    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):
4429class Hll(AggFunc):
4430    arg_types = {"this": True, "expressions": False}
4431    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4434class ApproxDistinct(AggFunc):
4435    arg_types = {"this": True, "accuracy": False}
4436    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4439class Array(Func):
4440    arg_types = {"expressions": False}
4441    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4445class ToArray(Func):
4446    pass
key = 'toarray'
class ToChar(Func):
4451class ToChar(Func):
4452    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class Convert(Func):
4456class Convert(Func):
4457    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4460class GenerateSeries(Func):
4461    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):
4464class ArrayAgg(AggFunc):
4465    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4468class ArrayUniqueAgg(AggFunc):
4469    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4472class ArrayAll(Func):
4473    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4477class ArrayAny(Func):
4478    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4481class ArrayConcat(Func):
4482    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4483    arg_types = {"this": True, "expressions": False}
4484    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4487class ArrayContains(Binary, Func):
4488    pass
key = 'arraycontains'
class ArrayContained(Binary):
4491class ArrayContained(Binary):
4492    pass
key = 'arraycontained'
class ArrayFilter(Func):
4495class ArrayFilter(Func):
4496    arg_types = {"this": True, "expression": True}
4497    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4500class ArrayJoin(Func):
4501    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4504class ArrayOverlaps(Binary, Func):
4505    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4508class ArraySize(Func):
4509    arg_types = {"this": True, "expression": False}
4510    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4513class ArraySort(Func):
4514    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4517class ArraySum(Func):
4518    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4521class ArrayUnionAgg(AggFunc):
4522    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4525class Avg(AggFunc):
4526    pass
key = 'avg'
class AnyValue(AggFunc):
4529class AnyValue(AggFunc):
4530    pass
key = 'anyvalue'
class Lag(AggFunc):
4533class Lag(AggFunc):
4534    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4537class Lead(AggFunc):
4538    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4543class First(AggFunc):
4544    pass
key = 'first'
class Last(AggFunc):
4547class Last(AggFunc):
4548    pass
key = 'last'
class FirstValue(AggFunc):
4551class FirstValue(AggFunc):
4552    pass
key = 'firstvalue'
class LastValue(AggFunc):
4555class LastValue(AggFunc):
4556    pass
key = 'lastvalue'
class NthValue(AggFunc):
4559class NthValue(AggFunc):
4560    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
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
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
key = 'case'
class Cast(Func):
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)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4586    @property
4587    def name(self) -> str:
4588        return self.this.name
to: DataType
4590    @property
4591    def to(self) -> DataType:
4592        return self.args["to"]
output_name: str
4594    @property
4595    def output_name(self) -> str:
4596        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:
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)

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):
4613class TryCast(Cast):
4614    pass
key = 'trycast'
class CastToStrType(Func):
4617class CastToStrType(Func):
4618    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4621class Collate(Binary, Func):
4622    pass
key = 'collate'
class Ceil(Func):
4625class Ceil(Func):
4626    arg_types = {"this": True, "decimals": False}
4627    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4630class Coalesce(Func):
4631    arg_types = {"this": True, "expressions": False}
4632    is_var_len_args = True
4633    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4636class Chr(Func):
4637    arg_types = {"this": True, "charset": False, "expressions": False}
4638    is_var_len_args = True
4639    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4642class Concat(Func):
4643    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4644    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4647class ConcatWs(Concat):
4648    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4652class ConnectByRoot(Func):
4653    pass
key = 'connectbyroot'
class Count(AggFunc):
4656class Count(AggFunc):
4657    arg_types = {"this": False, "expressions": False}
4658    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4661class CountIf(AggFunc):
4662    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4666class Cbrt(Func):
4667    pass
key = 'cbrt'
class CurrentDate(Func):
4670class CurrentDate(Func):
4671    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4674class CurrentDatetime(Func):
4675    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4678class CurrentTime(Func):
4679    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4682class CurrentTimestamp(Func):
4683    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4686class CurrentUser(Func):
4687    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4690class DateAdd(Func, IntervalOp):
4691    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4694class DateSub(Func, IntervalOp):
4695    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4698class DateDiff(Func, TimeUnit):
4699    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4700    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
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"]
DateTrunc(**args)
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)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4717    @property
4718    def unit(self) -> Expression:
4719        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4722class DatetimeAdd(Func, IntervalOp):
4723    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4726class DatetimeSub(Func, IntervalOp):
4727    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4730class DatetimeDiff(Func, TimeUnit):
4731    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4734class DatetimeTrunc(Func, TimeUnit):
4735    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4738class DayOfWeek(Func):
4739    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4742class DayOfMonth(Func):
4743    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4746class DayOfYear(Func):
4747    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4750class ToDays(Func):
4751    pass
key = 'todays'
class WeekOfYear(Func):
4754class WeekOfYear(Func):
4755    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4758class MonthsBetween(Func):
4759    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4762class LastDay(Func, TimeUnit):
4763    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4764    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4767class Extract(Func):
4768    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4771class Timestamp(Func):
4772    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4775class TimestampAdd(Func, TimeUnit):
4776    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4779class TimestampSub(Func, TimeUnit):
4780    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4783class TimestampDiff(Func, TimeUnit):
4784    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4785    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4788class TimestampTrunc(Func, TimeUnit):
4789    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4792class TimeAdd(Func, TimeUnit):
4793    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4796class TimeSub(Func, TimeUnit):
4797    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4800class TimeDiff(Func, TimeUnit):
4801    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4804class TimeTrunc(Func, TimeUnit):
4805    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4808class DateFromParts(Func):
4809    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4810    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
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    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4825class DateStrToDate(Func):
4826    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4829class DateToDateStr(Func):
4830    pass
key = 'datetodatestr'
class DateToDi(Func):
4833class DateToDi(Func):
4834    pass
key = 'datetodi'
class Date(Func):
4838class Date(Func):
4839    arg_types = {"this": False, "zone": False, "expressions": False}
4840    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4843class Day(Func):
4844    pass
key = 'day'
class Decode(Func):
4847class Decode(Func):
4848    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4851class DiToDate(Func):
4852    pass
key = 'ditodate'
class Encode(Func):
4855class Encode(Func):
4856    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4859class Exp(Func):
4860    pass
key = 'exp'
class Explode(Func):
4864class Explode(Func):
4865    arg_types = {"this": True, "expressions": False}
4866    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4869class ExplodeOuter(Explode):
4870    pass
key = 'explodeouter'
class Posexplode(Explode):
4873class Posexplode(Explode):
4874    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4877class PosexplodeOuter(Posexplode, ExplodeOuter):
4878    pass
key = 'posexplodeouter'
class Floor(Func):
4881class Floor(Func):
4882    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4885class FromBase64(Func):
4886    pass
key = 'frombase64'
class ToBase64(Func):
4889class ToBase64(Func):
4890    pass
key = 'tobase64'
class Greatest(Func):
4893class Greatest(Func):
4894    arg_types = {"this": True, "expressions": False}
4895    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4898class GroupConcat(AggFunc):
4899    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4902class Hex(Func):
4903    pass
key = 'hex'
class Xor(Connector, Func):
4906class Xor(Connector, Func):
4907    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4910class If(Func):
4911    arg_types = {"this": True, "true": True, "false": False}
4912    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4915class Nullif(Func):
4916    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4919class Initcap(Func):
4920    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4923class IsNan(Func):
4924    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4927class IsInf(Func):
4928    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
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 ""
arg_types = {'expressions': True}
output_name: str
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 ""

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):
4940class JSONPathPart(Expression):
4941    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4944class JSONPathFilter(JSONPathPart):
4945    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4948class JSONPathKey(JSONPathPart):
4949    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4952class JSONPathRecursive(JSONPathPart):
4953    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4956class JSONPathRoot(JSONPathPart):
4957    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4960class JSONPathScript(JSONPathPart):
4961    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4964class JSONPathSlice(JSONPathPart):
4965    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4968class JSONPathSelector(JSONPathPart):
4969    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4972class JSONPathSubscript(JSONPathPart):
4973    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4976class JSONPathUnion(JSONPathPart):
4977    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4980class JSONPathWildcard(JSONPathPart):
4981    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4984class FormatJson(Expression):
4985    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4988class JSONKeyValue(Expression):
4989    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
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    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
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    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5013class JSONArray(Func):
5014    arg_types = {
5015        "expressions": True,
5016        "null_handling": False,
5017        "return_type": False,
5018        "strict": False,
5019    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5023class JSONArrayAgg(Func):
5024    arg_types = {
5025        "this": True,
5026        "order": False,
5027        "null_handling": False,
5028        "return_type": False,
5029        "strict": False,
5030    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5035class JSONColumnDef(Expression):
5036    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):
5039class JSONSchema(Expression):
5040    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5044class JSONTable(Func):
5045    arg_types = {
5046        "this": True,
5047        "schema": True,
5048        "path": False,
5049        "error_handling": False,
5050        "empty_handling": False,
5051    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5054class OpenJSONColumnDef(Expression):
5055    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):
5058class OpenJSON(Func):
5059    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5062class JSONBContains(Binary):
5063    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
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 ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5071    @property
5072    def output_name(self) -> str:
5073        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):
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
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5081    @property
5082    def output_name(self) -> str:
5083        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):
5086class JSONBExtract(Binary, Func):
5087    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5090class JSONBExtractScalar(Binary, Func):
5091    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5094class JSONFormat(Func):
5095    arg_types = {"this": False, "options": False}
5096    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5100class JSONArrayContains(Binary, Predicate, Func):
5101    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
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
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5111class Least(Func):
5112    arg_types = {"this": True, "expressions": False}
5113    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5116class Left(Func):
5117    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5124class Length(Func):
5125    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
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    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5138class Ln(Func):
5139    pass
key = 'ln'
class Log(Func):
5142class Log(Func):
5143    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5146class Log2(Func):
5147    pass
key = 'log2'
class Log10(Func):
5150class Log10(Func):
5151    pass
key = 'log10'
class LogicalOr(AggFunc):
5154class LogicalOr(AggFunc):
5155    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5158class LogicalAnd(AggFunc):
5159    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5162class Lower(Func):
5163    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
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 []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5169    @property
5170    def keys(self) -> t.List[Expression]:
5171        keys = self.args.get("keys")
5172        return keys.expressions if keys else []
values: List[Expression]
5174    @property
5175    def values(self) -> t.List[Expression]:
5176        values = self.args.get("values")
5177        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5180class MapFromEntries(Func):
5181    pass
key = 'mapfromentries'
class StarMap(Func):
5184class StarMap(Func):
5185    pass
key = 'starmap'
class VarMap(Func):
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
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5192    @property
5193    def keys(self) -> t.List[Expression]:
5194        return self.args["keys"].expressions
values: List[Expression]
5196    @property
5197    def values(self) -> t.List[Expression]:
5198        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5202class MatchAgainst(Func):
5203    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5206class Max(AggFunc):
5207    arg_types = {"this": True, "expressions": False}
5208    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5211class MD5(Func):
5212    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5216class MD5Digest(Func):
5217    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5220class Min(AggFunc):
5221    arg_types = {"this": True, "expressions": False}
5222    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5225class Month(Func):
5226    pass
key = 'month'
class AddMonths(Func):
5229class AddMonths(Func):
5230    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5233class Nvl2(Func):
5234    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5238class Predict(Func):
5239    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5242class Pow(Binary, Func):
5243    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5246class PercentileCont(AggFunc):
5247    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5250class PercentileDisc(AggFunc):
5251    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5254class Quantile(AggFunc):
5255    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5258class ApproxQuantile(Quantile):
5259    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):
5262class Rand(Func):
5263    _sql_names = ["RAND", "RANDOM"]
5264    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5267class Randn(Func):
5268    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5271class RangeN(Func):
5272    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5275class ReadCSV(Func):
5276    _sql_names = ["READ_CSV"]
5277    is_var_len_args = True
5278    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5281class Reduce(Func):
5282    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):
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    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
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    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5308class RegexpLike(Binary, Func):
5309    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5312class RegexpILike(Binary, Func):
5313    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5318class RegexpSplit(Func):
5319    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5322class Repeat(Func):
5323    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5328class Round(Func):
5329    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5332class RowNumber(Func):
5333    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5336class SafeDivide(Func):
5337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5340class SHA(Func):
5341    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5344class SHA2(Func):
5345    _sql_names = ["SHA2"]
5346    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5349class Sign(Func):
5350    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5353class SortArray(Func):
5354    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5357class Split(Func):
5358    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5363class Substring(Func):
5364    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5367class StandardHash(Func):
5368    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5371class StartsWith(Func):
5372    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5373    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5376class StrPosition(Func):
5377    arg_types = {
5378        "this": True,
5379        "substr": True,
5380        "position": False,
5381        "instance": False,
5382    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5385class StrToDate(Func):
5386    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5389class StrToTime(Func):
5390    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5395class StrToUnix(Func):
5396    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5401class StrToMap(Func):
5402    arg_types = {
5403        "this": True,
5404        "pair_delim": False,
5405        "key_value_delim": False,
5406        "duplicate_resolution_callback": False,
5407    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5410class NumberToStr(Func):
5411    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5414class FromBase(Func):
5415    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5418class Struct(Func):
5419    arg_types = {"expressions": False}
5420    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5423class StructExtract(Func):
5424    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5429class Stuff(Func):
5430    _sql_names = ["STUFF", "INSERT"]
5431    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):
5434class Sum(AggFunc):
5435    pass
key = 'sum'
class Sqrt(Func):
5438class Sqrt(Func):
5439    pass
key = 'sqrt'
class Stddev(AggFunc):
5442class Stddev(AggFunc):
5443    pass
key = 'stddev'
class StddevPop(AggFunc):
5446class StddevPop(AggFunc):
5447    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5450class StddevSamp(AggFunc):
5451    pass
key = 'stddevsamp'
class TimeToStr(Func):
5454class TimeToStr(Func):
5455    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5458class TimeToTimeStr(Func):
5459    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5462class TimeToUnix(Func):
5463    pass
key = 'timetounix'
class TimeStrToDate(Func):
5466class TimeStrToDate(Func):
5467    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5470class TimeStrToTime(Func):
5471    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5474class TimeStrToUnix(Func):
5475    pass
key = 'timestrtounix'
class Trim(Func):
5478class Trim(Func):
5479    arg_types = {
5480        "this": True,
5481        "expression": False,
5482        "position": False,
5483        "collation": False,
5484    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
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)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
5491    @property
5492    def return_type(self) -> DataType:
5493        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5496class TsOrDsDiff(Func, TimeUnit):
5497    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5500class TsOrDsToDateStr(Func):
5501    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5504class TsOrDsToDate(Func):
5505    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5508class TsOrDsToTime(Func):
5509    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5512class TsOrDiToDi(Func):
5513    pass
key = 'tsorditodi'
class Unhex(Func):
5516class Unhex(Func):
5517    pass
key = 'unhex'
class UnixDate(Func):
5521class UnixDate(Func):
5522    pass
key = 'unixdate'
class UnixToStr(Func):
5525class UnixToStr(Func):
5526    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
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)
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):
5546class UnixToTimeStr(Func):
5547    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
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    }
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):
5565class Upper(Func):
5566    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5569class Variance(AggFunc):
5570    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5573class VariancePop(AggFunc):
5574    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5577class Week(Func):
5578    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5581class XMLTable(Func):
5582    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):
5585class Year(Func):
5586    pass
key = 'year'
class Use(Expression):
5589class Use(Expression):
5590    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5593class Merge(Expression):
5594    arg_types = {
5595        "this": True,
5596        "using": True,
5597        "on": True,
5598        "expressions": True,
5599        "with": False,
5600    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5603class When(Func):
5604    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):
5609class NextValueFor(Func):
5610    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:
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)

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):
5704def maybe_copy(instance, copy=True):
5705    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:
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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:
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}")

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

Replace children of an expression with the result of a lambda fun(child) -> exp.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
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    }

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

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

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

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

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

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

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:
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=[])

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

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

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

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:
7178def true() -> Boolean:
7179    """
7180    Returns a true Boolean expression.
7181    """
7182    return Boolean(this=True)

Returns a true Boolean expression.

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

Returns a false Boolean expression.

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

Returns a Null expression.