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

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
293    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
294        if self.comments is None:
295            self.comments = []
296        if comments:
297            for comment in comments:
298                _, *meta = comment.split(SQLGLOT_META)
299                if meta:
300                    for kv in "".join(meta).split(","):
301                        k, *v = kv.split("=")
302                        value = v[0].strip() if v else True
303                        self.meta[k.strip()] = value
304                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
306    def append(self, arg_key: str, value: t.Any) -> None:
307        """
308        Appends value to arg_key if it's a list or sets it as a new list.
309
310        Args:
311            arg_key (str): name of the list expression arg
312            value (Any): value to append to the list
313        """
314        if type(self.args.get(arg_key)) is not list:
315            self.args[arg_key] = []
316        self.args[arg_key].append(value)
317        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:
319    def set(self, arg_key: str, value: t.Any) -> None:
320        """
321        Sets arg_key to value.
322
323        Args:
324            arg_key: name of the expression arg.
325            value: value to set the arg to.
326        """
327        if value is None:
328            self.args.pop(arg_key, None)
329            return
330
331        self.args[arg_key] = value
332        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
344    @property
345    def depth(self) -> int:
346        """
347        Returns the depth of this tree.
348        """
349        if self.parent:
350            return self.parent.depth + 1
351        return 0

Returns the depth of this tree.

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

Returns the parent select statement.

same_parent: bool
416    @property
417    def same_parent(self) -> bool:
418        """Returns if the parent is the same class as itself."""
419        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
421    def root(self) -> Expression:
422        """
423        Returns the root expression of this tree.
424        """
425        expression = self
426        while expression.parent:
427            expression = expression.parent
428        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
430    def walk(self, bfs=True, prune=None):
431        """
432        Returns a generator object which visits all nodes in this tree.
433
434        Args:
435            bfs (bool): if set to True the BFS traversal order will be applied,
436                otherwise the DFS traversal will be used instead.
437            prune ((node, parent, arg_key) -> bool): callable that returns True if
438                the generator should stop traversing this branch of the tree.
439
440        Returns:
441            the generator object.
442        """
443        if bfs:
444            yield from self.bfs(prune=prune)
445        else:
446            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):
448    def dfs(self, parent=None, key=None, prune=None):
449        """
450        Returns a generator object which visits all nodes in this tree in
451        the DFS (Depth-first) order.
452
453        Returns:
454            The generator object.
455        """
456        parent = parent or self.parent
457        yield self, parent, key
458        if prune and prune(self, parent, key):
459            return
460
461        for k, v in self.iter_expressions():
462            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):
464    def bfs(self, prune=None):
465        """
466        Returns a generator object which visits all nodes in this tree in
467        the BFS (Breadth-first) order.
468
469        Returns:
470            The generator object.
471        """
472        queue = deque([(self, self.parent, None)])
473
474        while queue:
475            item, parent, key = queue.popleft()
476
477            yield item, parent, key
478            if prune and prune(item, parent, key):
479                continue
480
481            for k, v in item.iter_expressions():
482                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):
484    def unnest(self):
485        """
486        Returns the first non parenthesis child or self.
487        """
488        expression = self
489        while type(expression) is Paren:
490            expression = expression.this
491        return expression

Returns the first non parenthesis child or self.

def unalias(self):
493    def unalias(self):
494        """
495        Returns the inner expression if this is an Alias.
496        """
497        if isinstance(self, Alias):
498            return self.this
499        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
501    def unnest_operands(self):
502        """
503        Returns unnested operands as a tuple.
504        """
505        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
507    def flatten(self, unnest=True):
508        """
509        Returns a generator which yields child nodes whose parents are the same class.
510
511        A AND B AND C -> [A, B, C]
512        """
513        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and type(n) is not self.__class__):
514            if type(node) is not self.__class__:
515                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:
523    def to_s(self) -> str:
524        """
525        Same as __repr__, but includes additional information which can be useful
526        for debugging, like empty or missing args and the AST nodes' object IDs.
527        """
528        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:
530    def sql(self, dialect: DialectType = None, **opts) -> str:
531        """
532        Returns SQL string representation of this tree.
533
534        Args:
535            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
536            opts: other `sqlglot.generator.Generator` options.
537
538        Returns:
539            The SQL string.
540        """
541        from sqlglot.dialects import Dialect
542
543        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):
545    def transform(self, fun, *args, copy=True, **kwargs):
546        """
547        Recursively visits all tree nodes (excluding already transformed ones)
548        and applies the given transformation function to each node.
549
550        Args:
551            fun (function): a function which takes a node as an argument and returns a
552                new transformed node or the same node without modifications. If the function
553                returns None, then the corresponding node will be removed from the syntax tree.
554            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
555                modified in place.
556
557        Returns:
558            The transformed tree.
559        """
560        node = self.copy() if copy else self
561        new_node = fun(node, *args, **kwargs)
562
563        if new_node is None or not isinstance(new_node, Expression):
564            return new_node
565        if new_node is not node:
566            new_node.parent = node.parent
567            return new_node
568
569        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
570        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):
578    def replace(self, expression):
579        """
580        Swap out this expression with a new expression.
581
582        For example::
583
584            >>> tree = Select().select("x").from_("tbl")
585            >>> tree.find(Column).replace(column("y"))
586            Column(
587              this=Identifier(this=y, quoted=False))
588            >>> tree.sql()
589            'SELECT y FROM tbl'
590
591        Args:
592            expression: new node
593
594        Returns:
595            The new expression or expressions.
596        """
597        if not self.parent:
598            return expression
599
600        parent = self.parent
601        self.parent = None
602
603        replace_children(parent, lambda child: expression if child is self else child)
604        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:
606    def pop(self: E) -> E:
607        """
608        Remove this expression from its AST.
609
610        Returns:
611            The popped expression.
612        """
613        self.replace(None)
614        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
676    @classmethod
677    def load(cls, obj):
678        """
679        Load a dict (as returned by `Expression.dump`) into an Expression instance.
680        """
681        from sqlglot.serde import load
682
683        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:
685    def and_(
686        self,
687        *expressions: t.Optional[ExpOrStr],
688        dialect: DialectType = None,
689        copy: bool = True,
690        **opts,
691    ) -> Condition:
692        """
693        AND this condition with one or multiple expressions.
694
695        Example:
696            >>> condition("x=1").and_("y=1").sql()
697            'x = 1 AND y = 1'
698
699        Args:
700            *expressions: the SQL code strings to parse.
701                If an `Expression` instance is passed, it will be used as-is.
702            dialect: the dialect used to parse the input expression.
703            copy: whether to copy the involved expressions (only applies to Expressions).
704            opts: other options to use to parse the input expressions.
705
706        Returns:
707            The new And condition.
708        """
709        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:
711    def or_(
712        self,
713        *expressions: t.Optional[ExpOrStr],
714        dialect: DialectType = None,
715        copy: bool = True,
716        **opts,
717    ) -> Condition:
718        """
719        OR this condition with one or multiple expressions.
720
721        Example:
722            >>> condition("x=1").or_("y=1").sql()
723            'x = 1 OR y = 1'
724
725        Args:
726            *expressions: the SQL code strings to parse.
727                If an `Expression` instance is passed, it will be used as-is.
728            dialect: the dialect used to parse the input expression.
729            copy: whether to copy the involved expressions (only applies to Expressions).
730            opts: other options to use to parse the input expressions.
731
732        Returns:
733            The new Or condition.
734        """
735        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):
737    def not_(self, copy: bool = True):
738        """
739        Wrap this condition with NOT.
740
741        Example:
742            >>> condition("x=1").not_().sql()
743            'NOT x = 1'
744
745        Args:
746            copy: whether to copy this object.
747
748        Returns:
749            The new Not instance.
750        """
751        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:
753    def as_(
754        self,
755        alias: str | Identifier,
756        quoted: t.Optional[bool] = None,
757        dialect: DialectType = None,
758        copy: bool = True,
759        **opts,
760    ) -> Alias:
761        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:
786    def isin(
787        self,
788        *expressions: t.Any,
789        query: t.Optional[ExpOrStr] = None,
790        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
791        copy: bool = True,
792        **opts,
793    ) -> In:
794        return In(
795            this=maybe_copy(self, copy),
796            expressions=[convert(e, copy=copy) for e in expressions],
797            query=maybe_parse(query, copy=copy, **opts) if query else None,
798            unnest=(
799                Unnest(
800                    expressions=[
801                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
802                        for e in ensure_list(unnest)
803                    ]
804                )
805                if unnest
806                else None
807            ),
808        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
810    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
811        return Between(
812            this=maybe_copy(self, copy),
813            low=convert(low, copy=copy, **opts),
814            high=convert(high, copy=copy, **opts),
815        )
def is_( self, other: Union[str, Expression]) -> Is:
817    def is_(self, other: ExpOrStr) -> Is:
818        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
820    def like(self, other: ExpOrStr) -> Like:
821        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
823    def ilike(self, other: ExpOrStr) -> ILike:
824        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
826    def eq(self, other: t.Any) -> EQ:
827        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
829    def neq(self, other: t.Any) -> NEQ:
830        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
832    def rlike(self, other: ExpOrStr) -> RegexpLike:
833        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
835    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
836        div = self._binop(Div, other)
837        div.args["typed"] = typed
838        div.args["safe"] = safe
839        return div
def desc(self, nulls_first: bool = False) -> Ordered:
841    def desc(self, nulls_first: bool = False) -> Ordered:
842        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):
925class Condition(Expression):
926    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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]
991    @property
992    def ctes(self) -> t.List[CTE]:
993        """Returns a list of all the CTEs attached to this query."""
994        with_ = self.args.get("with")
995        return with_.expressions if with_ else []

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

selects: List[Expression]
 997    @property
 998    def selects(self) -> t.List[Expression]:
 999        """Returns the query's projections."""
1000        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1002    @property
1003    def named_selects(self) -> t.List[str]:
1004        """Returns the output names of the query's projections."""
1005        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:
1007    def select(
1008        self,
1009        *expressions: t.Optional[ExpOrStr],
1010        append: bool = True,
1011        dialect: DialectType = None,
1012        copy: bool = True,
1013        **opts,
1014    ) -> Query:
1015        """
1016        Append to or set the SELECT expressions.
1017
1018        Example:
1019            >>> Select().select("x", "y").sql()
1020            'SELECT x, y'
1021
1022        Args:
1023            *expressions: the SQL code strings to parse.
1024                If an `Expression` instance is passed, it will be used as-is.
1025            append: if `True`, add to any existing expressions.
1026                Otherwise, this resets the expressions.
1027            dialect: the dialect used to parse the input expressions.
1028            copy: if `False`, modify this expression instance in-place.
1029            opts: other options to use to parse the input expressions.
1030
1031        Returns:
1032            The modified Query expression.
1033        """
1034        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:
1036    def with_(
1037        self,
1038        alias: ExpOrStr,
1039        as_: ExpOrStr,
1040        recursive: t.Optional[bool] = None,
1041        append: bool = True,
1042        dialect: DialectType = None,
1043        copy: bool = True,
1044        **opts,
1045    ) -> Query:
1046        """
1047        Append to or set the common table expressions.
1048
1049        Example:
1050            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1051            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1052
1053        Args:
1054            alias: the SQL code string to parse as the table name.
1055                If an `Expression` instance is passed, this is used as-is.
1056            as_: the SQL code string to parse as the table expression.
1057                If an `Expression` instance is passed, it will be used as-is.
1058            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1059            append: if `True`, add to any existing expressions.
1060                Otherwise, this resets the expressions.
1061            dialect: the dialect used to parse the input expression.
1062            copy: if `False`, modify this expression instance in-place.
1063            opts: other options to use to parse the input expressions.
1064
1065        Returns:
1066            The modified expression.
1067        """
1068        return _apply_cte_builder(
1069            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1070        )

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:
1072    def union(
1073        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1074    ) -> Union:
1075        """
1076        Builds a UNION expression.
1077
1078        Example:
1079            >>> import sqlglot
1080            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1081            'SELECT * FROM foo UNION SELECT * FROM bla'
1082
1083        Args:
1084            expression: the SQL code string.
1085                If an `Expression` instance is passed, it will be used as-is.
1086            distinct: set the DISTINCT flag if and only if this is true.
1087            dialect: the dialect used to parse the input expression.
1088            opts: other options to use to parse the input expressions.
1089
1090        Returns:
1091            The new Union expression.
1092        """
1093        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:
1095    def intersect(
1096        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1097    ) -> Intersect:
1098        """
1099        Builds an INTERSECT expression.
1100
1101        Example:
1102            >>> import sqlglot
1103            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1104            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1105
1106        Args:
1107            expression: the SQL code string.
1108                If an `Expression` instance is passed, it will be used as-is.
1109            distinct: set the DISTINCT flag if and only if this is true.
1110            dialect: the dialect used to parse the input expression.
1111            opts: other options to use to parse the input expressions.
1112
1113        Returns:
1114            The new Intersect expression.
1115        """
1116        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:
1118    def except_(
1119        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1120    ) -> Except:
1121        """
1122        Builds an EXCEPT expression.
1123
1124        Example:
1125            >>> import sqlglot
1126            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1127            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1128
1129        Args:
1130            expression: the SQL code string.
1131                If an `Expression` instance is passed, it will be used as-is.
1132            distinct: set the DISTINCT flag if and only if this is true.
1133            dialect: the dialect used to parse the input expression.
1134            opts: other options to use to parse the input expressions.
1135
1136        Returns:
1137            The new Except expression.
1138        """
1139        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):
1142class UDTF(DerivedTable):
1143    @property
1144    def selects(self) -> t.List[Expression]:
1145        alias = self.args.get("alias")
1146        return alias.columns if alias else []
selects: List[Expression]
1143    @property
1144    def selects(self) -> t.List[Expression]:
1145        alias = self.args.get("alias")
1146        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1149class Cache(Expression):
1150    arg_types = {
1151        "this": True,
1152        "lazy": False,
1153        "options": False,
1154        "expression": False,
1155    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1158class Uncache(Expression):
1159    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1162class Refresh(Expression):
1163    pass
key = 'refresh'
class DDL(Expression):
1166class DDL(Expression):
1167    @property
1168    def ctes(self) -> t.List[CTE]:
1169        """Returns a list of all the CTEs attached to this statement."""
1170        with_ = self.args.get("with")
1171        return with_.expressions if with_ else []
1172
1173    @property
1174    def selects(self) -> t.List[Expression]:
1175        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1176        return self.expression.selects if isinstance(self.expression, Query) else []
1177
1178    @property
1179    def named_selects(self) -> t.List[str]:
1180        """
1181        If this statement contains a query (e.g. a CTAS), this returns the output
1182        names of the query's projections.
1183        """
1184        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1167    @property
1168    def ctes(self) -> t.List[CTE]:
1169        """Returns a list of all the CTEs attached to this statement."""
1170        with_ = self.args.get("with")
1171        return with_.expressions if with_ else []

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

selects: List[Expression]
1173    @property
1174    def selects(self) -> t.List[Expression]:
1175        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1176        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]
1178    @property
1179    def named_selects(self) -> t.List[str]:
1180        """
1181        If this statement contains a query (e.g. a CTAS), this returns the output
1182        names of the query's projections.
1183        """
1184        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):
1187class DML(Expression):
1188    def returning(
1189        self,
1190        expression: ExpOrStr,
1191        dialect: DialectType = None,
1192        copy: bool = True,
1193        **opts,
1194    ) -> DML:
1195        """
1196        Set the RETURNING expression. Not supported by all dialects.
1197
1198        Example:
1199            >>> delete("tbl").returning("*", dialect="postgres").sql()
1200            'DELETE FROM tbl RETURNING *'
1201
1202        Args:
1203            expression: the SQL code strings to parse.
1204                If an `Expression` instance is passed, it will be used as-is.
1205            dialect: the dialect used to parse the input expressions.
1206            copy: if `False`, modify this expression instance in-place.
1207            opts: other options to use to parse the input expressions.
1208
1209        Returns:
1210            Delete: the modified expression.
1211        """
1212        return _apply_builder(
1213            expression=expression,
1214            instance=self,
1215            arg="returning",
1216            prefix="RETURNING",
1217            dialect=dialect,
1218            copy=copy,
1219            into=Returning,
1220            **opts,
1221        )
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:
1188    def returning(
1189        self,
1190        expression: ExpOrStr,
1191        dialect: DialectType = None,
1192        copy: bool = True,
1193        **opts,
1194    ) -> DML:
1195        """
1196        Set the RETURNING expression. Not supported by all dialects.
1197
1198        Example:
1199            >>> delete("tbl").returning("*", dialect="postgres").sql()
1200            'DELETE FROM tbl RETURNING *'
1201
1202        Args:
1203            expression: the SQL code strings to parse.
1204                If an `Expression` instance is passed, it will be used as-is.
1205            dialect: the dialect used to parse the input expressions.
1206            copy: if `False`, modify this expression instance in-place.
1207            opts: other options to use to parse the input expressions.
1208
1209        Returns:
1210            Delete: the modified expression.
1211        """
1212        return _apply_builder(
1213            expression=expression,
1214            instance=self,
1215            arg="returning",
1216            prefix="RETURNING",
1217            dialect=dialect,
1218            copy=copy,
1219            into=Returning,
1220            **opts,
1221        )

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):
1224class Create(DDL):
1225    arg_types = {
1226        "with": False,
1227        "this": True,
1228        "kind": True,
1229        "expression": False,
1230        "exists": False,
1231        "properties": False,
1232        "replace": False,
1233        "unique": False,
1234        "indexes": False,
1235        "no_schema_binding": False,
1236        "begin": False,
1237        "end": False,
1238        "clone": False,
1239    }
1240
1241    @property
1242    def kind(self) -> t.Optional[str]:
1243        kind = self.args.get("kind")
1244        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]
1241    @property
1242    def kind(self) -> t.Optional[str]:
1243        kind = self.args.get("kind")
1244        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1247class SequenceProperties(Expression):
1248    arg_types = {
1249        "increment": False,
1250        "minvalue": False,
1251        "maxvalue": False,
1252        "cache": False,
1253        "start": False,
1254        "owned": False,
1255        "options": False,
1256    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1259class TruncateTable(Expression):
1260    arg_types = {
1261        "expressions": True,
1262        "is_database": False,
1263        "exists": False,
1264        "only": False,
1265        "cluster": False,
1266        "identity": False,
1267        "option": False,
1268        "partition": False,
1269    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1275class Clone(Expression):
1276    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1279class Describe(Expression):
1280    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):
1283class Kill(Expression):
1284    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1287class Pragma(Expression):
1288    pass
key = 'pragma'
class Set(Expression):
1291class Set(Expression):
1292    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1295class Heredoc(Expression):
1296    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1299class SetItem(Expression):
1300    arg_types = {
1301        "this": False,
1302        "expressions": False,
1303        "kind": False,
1304        "collate": False,  # MySQL SET NAMES statement
1305        "global": False,
1306    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1309class Show(Expression):
1310    arg_types = {
1311        "this": True,
1312        "history": False,
1313        "terse": False,
1314        "target": False,
1315        "offset": False,
1316        "starts_with": False,
1317        "limit": False,
1318        "from": False,
1319        "like": False,
1320        "where": False,
1321        "db": False,
1322        "scope": False,
1323        "scope_kind": False,
1324        "full": False,
1325        "mutex": False,
1326        "query": False,
1327        "channel": False,
1328        "global": False,
1329        "log": False,
1330        "position": False,
1331        "types": False,
1332    }
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):
1335class UserDefinedFunction(Expression):
1336    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1339class CharacterSet(Expression):
1340    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1343class With(Expression):
1344    arg_types = {"expressions": True, "recursive": False}
1345
1346    @property
1347    def recursive(self) -> bool:
1348        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1346    @property
1347    def recursive(self) -> bool:
1348        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1351class WithinGroup(Expression):
1352    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1357class CTE(DerivedTable):
1358    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1361class TableAlias(Expression):
1362    arg_types = {"this": False, "columns": False}
1363
1364    @property
1365    def columns(self):
1366        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1364    @property
1365    def columns(self):
1366        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1369class BitString(Condition):
1370    pass
key = 'bitstring'
class HexString(Condition):
1373class HexString(Condition):
1374    pass
key = 'hexstring'
class ByteString(Condition):
1377class ByteString(Condition):
1378    pass
key = 'bytestring'
class RawString(Condition):
1381class RawString(Condition):
1382    pass
key = 'rawstring'
class UnicodeString(Condition):
1385class UnicodeString(Condition):
1386    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1389class Column(Condition):
1390    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1391
1392    @property
1393    def table(self) -> str:
1394        return self.text("table")
1395
1396    @property
1397    def db(self) -> str:
1398        return self.text("db")
1399
1400    @property
1401    def catalog(self) -> str:
1402        return self.text("catalog")
1403
1404    @property
1405    def output_name(self) -> str:
1406        return self.name
1407
1408    @property
1409    def parts(self) -> t.List[Identifier]:
1410        """Return the parts of a column in order catalog, db, table, name."""
1411        return [
1412            t.cast(Identifier, self.args[part])
1413            for part in ("catalog", "db", "table", "this")
1414            if self.args.get(part)
1415        ]
1416
1417    def to_dot(self) -> Dot | Identifier:
1418        """Converts the column into a dot expression."""
1419        parts = self.parts
1420        parent = self.parent
1421
1422        while parent:
1423            if isinstance(parent, Dot):
1424                parts.append(parent.expression)
1425            parent = parent.parent
1426
1427        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
1392    @property
1393    def table(self) -> str:
1394        return self.text("table")
db: str
1396    @property
1397    def db(self) -> str:
1398        return self.text("db")
catalog: str
1400    @property
1401    def catalog(self) -> str:
1402        return self.text("catalog")
output_name: str
1404    @property
1405    def output_name(self) -> str:
1406        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]
1408    @property
1409    def parts(self) -> t.List[Identifier]:
1410        """Return the parts of a column in order catalog, db, table, name."""
1411        return [
1412            t.cast(Identifier, self.args[part])
1413            for part in ("catalog", "db", "table", "this")
1414            if self.args.get(part)
1415        ]

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

def to_dot(self) -> Dot | Identifier:
1417    def to_dot(self) -> Dot | Identifier:
1418        """Converts the column into a dot expression."""
1419        parts = self.parts
1420        parent = self.parent
1421
1422        while parent:
1423            if isinstance(parent, Dot):
1424                parts.append(parent.expression)
1425            parent = parent.parent
1426
1427        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1430class ColumnPosition(Expression):
1431    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1434class ColumnDef(Expression):
1435    arg_types = {
1436        "this": True,
1437        "kind": False,
1438        "constraints": False,
1439        "exists": False,
1440        "position": False,
1441    }
1442
1443    @property
1444    def constraints(self) -> t.List[ColumnConstraint]:
1445        return self.args.get("constraints") or []
1446
1447    @property
1448    def kind(self) -> t.Optional[DataType]:
1449        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1443    @property
1444    def constraints(self) -> t.List[ColumnConstraint]:
1445        return self.args.get("constraints") or []
kind: Optional[DataType]
1447    @property
1448    def kind(self) -> t.Optional[DataType]:
1449        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1452class AlterColumn(Expression):
1453    arg_types = {
1454        "this": True,
1455        "dtype": False,
1456        "collate": False,
1457        "using": False,
1458        "default": False,
1459        "drop": False,
1460        "comment": False,
1461    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1464class RenameColumn(Expression):
1465    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1468class RenameTable(Expression):
1469    pass
key = 'renametable'
class SwapTable(Expression):
1472class SwapTable(Expression):
1473    pass
key = 'swaptable'
class Comment(Expression):
1476class Comment(Expression):
1477    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):
1480class Comprehension(Expression):
1481    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):
1485class MergeTreeTTLAction(Expression):
1486    arg_types = {
1487        "this": True,
1488        "delete": False,
1489        "recompress": False,
1490        "to_disk": False,
1491        "to_volume": False,
1492    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1496class MergeTreeTTL(Expression):
1497    arg_types = {
1498        "expressions": True,
1499        "where": False,
1500        "group": False,
1501        "aggregates": False,
1502    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1506class IndexConstraintOption(Expression):
1507    arg_types = {
1508        "key_block_size": False,
1509        "using": False,
1510        "parser": False,
1511        "comment": False,
1512        "visible": False,
1513        "engine_attr": False,
1514        "secondary_engine_attr": False,
1515    }
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):
1518class ColumnConstraint(Expression):
1519    arg_types = {"this": False, "kind": True}
1520
1521    @property
1522    def kind(self) -> ColumnConstraintKind:
1523        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1521    @property
1522    def kind(self) -> ColumnConstraintKind:
1523        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1526class ColumnConstraintKind(Expression):
1527    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1530class AutoIncrementColumnConstraint(ColumnConstraintKind):
1531    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1534class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1535    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1538class CaseSpecificColumnConstraint(ColumnConstraintKind):
1539    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1542class CharacterSetColumnConstraint(ColumnConstraintKind):
1543    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1546class CheckColumnConstraint(ColumnConstraintKind):
1547    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1550class ClusteredColumnConstraint(ColumnConstraintKind):
1551    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1554class CollateColumnConstraint(ColumnConstraintKind):
1555    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1558class CommentColumnConstraint(ColumnConstraintKind):
1559    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1562class CompressColumnConstraint(ColumnConstraintKind):
1563    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1566class DateFormatColumnConstraint(ColumnConstraintKind):
1567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1570class DefaultColumnConstraint(ColumnConstraintKind):
1571    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1574class EncodeColumnConstraint(ColumnConstraintKind):
1575    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1578class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1579    # this: True -> ALWAYS, this: False -> BY DEFAULT
1580    arg_types = {
1581        "this": False,
1582        "expression": False,
1583        "on_null": False,
1584        "start": False,
1585        "increment": False,
1586        "minvalue": False,
1587        "maxvalue": False,
1588        "cycle": False,
1589    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1592class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1593    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1597class IndexColumnConstraint(ColumnConstraintKind):
1598    arg_types = {
1599        "this": False,
1600        "schema": True,
1601        "kind": False,
1602        "index_type": False,
1603        "options": False,
1604    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1607class InlineLengthColumnConstraint(ColumnConstraintKind):
1608    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1611class NonClusteredColumnConstraint(ColumnConstraintKind):
1612    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1615class NotForReplicationColumnConstraint(ColumnConstraintKind):
1616    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1619class NotNullColumnConstraint(ColumnConstraintKind):
1620    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1624class OnUpdateColumnConstraint(ColumnConstraintKind):
1625    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1629class TransformColumnConstraint(ColumnConstraintKind):
1630    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1633class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1634    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1637class TitleColumnConstraint(ColumnConstraintKind):
1638    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1641class UniqueColumnConstraint(ColumnConstraintKind):
1642    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1645class UppercaseColumnConstraint(ColumnConstraintKind):
1646    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1649class PathColumnConstraint(ColumnConstraintKind):
1650    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1655class ComputedColumnConstraint(ColumnConstraintKind):
1656    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1659class Constraint(Expression):
1660    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1663class Delete(DML):
1664    arg_types = {
1665        "with": False,
1666        "this": False,
1667        "using": False,
1668        "where": False,
1669        "returning": False,
1670        "limit": False,
1671        "tables": False,  # Multiple-Table Syntax (MySQL)
1672    }
1673
1674    def delete(
1675        self,
1676        table: ExpOrStr,
1677        dialect: DialectType = None,
1678        copy: bool = True,
1679        **opts,
1680    ) -> Delete:
1681        """
1682        Create a DELETE expression or replace the table on an existing DELETE expression.
1683
1684        Example:
1685            >>> delete("tbl").sql()
1686            'DELETE FROM tbl'
1687
1688        Args:
1689            table: the table from which to delete.
1690            dialect: the dialect used to parse the input expression.
1691            copy: if `False`, modify this expression instance in-place.
1692            opts: other options to use to parse the input expressions.
1693
1694        Returns:
1695            Delete: the modified expression.
1696        """
1697        return _apply_builder(
1698            expression=table,
1699            instance=self,
1700            arg="this",
1701            dialect=dialect,
1702            into=Table,
1703            copy=copy,
1704            **opts,
1705        )
1706
1707    def where(
1708        self,
1709        *expressions: t.Optional[ExpOrStr],
1710        append: bool = True,
1711        dialect: DialectType = None,
1712        copy: bool = True,
1713        **opts,
1714    ) -> Delete:
1715        """
1716        Append to or set the WHERE expressions.
1717
1718        Example:
1719            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1720            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1721
1722        Args:
1723            *expressions: the SQL code strings to parse.
1724                If an `Expression` instance is passed, it will be used as-is.
1725                Multiple expressions are combined with an AND operator.
1726            append: if `True`, AND the new expressions to any existing expression.
1727                Otherwise, this resets the expression.
1728            dialect: the dialect used to parse the input expressions.
1729            copy: if `False`, modify this expression instance in-place.
1730            opts: other options to use to parse the input expressions.
1731
1732        Returns:
1733            Delete: the modified expression.
1734        """
1735        return _apply_conjunction_builder(
1736            *expressions,
1737            instance=self,
1738            arg="where",
1739            append=append,
1740            into=Where,
1741            dialect=dialect,
1742            copy=copy,
1743            **opts,
1744        )
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:
1674    def delete(
1675        self,
1676        table: ExpOrStr,
1677        dialect: DialectType = None,
1678        copy: bool = True,
1679        **opts,
1680    ) -> Delete:
1681        """
1682        Create a DELETE expression or replace the table on an existing DELETE expression.
1683
1684        Example:
1685            >>> delete("tbl").sql()
1686            'DELETE FROM tbl'
1687
1688        Args:
1689            table: the table from which to delete.
1690            dialect: the dialect used to parse the input expression.
1691            copy: if `False`, modify this expression instance in-place.
1692            opts: other options to use to parse the input expressions.
1693
1694        Returns:
1695            Delete: the modified expression.
1696        """
1697        return _apply_builder(
1698            expression=table,
1699            instance=self,
1700            arg="this",
1701            dialect=dialect,
1702            into=Table,
1703            copy=copy,
1704            **opts,
1705        )

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:
1707    def where(
1708        self,
1709        *expressions: t.Optional[ExpOrStr],
1710        append: bool = True,
1711        dialect: DialectType = None,
1712        copy: bool = True,
1713        **opts,
1714    ) -> Delete:
1715        """
1716        Append to or set the WHERE expressions.
1717
1718        Example:
1719            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1720            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1721
1722        Args:
1723            *expressions: the SQL code strings to parse.
1724                If an `Expression` instance is passed, it will be used as-is.
1725                Multiple expressions are combined with an AND operator.
1726            append: if `True`, AND the new expressions to any existing expression.
1727                Otherwise, this resets the expression.
1728            dialect: the dialect used to parse the input expressions.
1729            copy: if `False`, modify this expression instance in-place.
1730            opts: other options to use to parse the input expressions.
1731
1732        Returns:
1733            Delete: the modified expression.
1734        """
1735        return _apply_conjunction_builder(
1736            *expressions,
1737            instance=self,
1738            arg="where",
1739            append=append,
1740            into=Where,
1741            dialect=dialect,
1742            copy=copy,
1743            **opts,
1744        )

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):
1747class Drop(Expression):
1748    arg_types = {
1749        "this": False,
1750        "kind": False,
1751        "exists": False,
1752        "temporary": False,
1753        "materialized": False,
1754        "cascade": False,
1755        "constraints": False,
1756        "purge": False,
1757    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1760class Filter(Expression):
1761    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1764class Check(Expression):
1765    pass
key = 'check'
class Connect(Expression):
1769class Connect(Expression):
1770    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1773class Prior(Expression):
1774    pass
key = 'prior'
class Directory(Expression):
1777class Directory(Expression):
1778    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1779    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1782class ForeignKey(Expression):
1783    arg_types = {
1784        "expressions": True,
1785        "reference": False,
1786        "delete": False,
1787        "update": False,
1788    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1791class ColumnPrefix(Expression):
1792    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1795class PrimaryKey(Expression):
1796    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1801class Into(Expression):
1802    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1805class From(Expression):
1806    @property
1807    def name(self) -> str:
1808        return self.this.name
1809
1810    @property
1811    def alias_or_name(self) -> str:
1812        return self.this.alias_or_name
name: str
1806    @property
1807    def name(self) -> str:
1808        return self.this.name
alias_or_name: str
1810    @property
1811    def alias_or_name(self) -> str:
1812        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1815class Having(Expression):
1816    pass
key = 'having'
class Hint(Expression):
1819class Hint(Expression):
1820    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1823class JoinHint(Expression):
1824    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1827class Identifier(Expression):
1828    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1829
1830    @property
1831    def quoted(self) -> bool:
1832        return bool(self.args.get("quoted"))
1833
1834    @property
1835    def hashable_args(self) -> t.Any:
1836        return (self.this, self.quoted)
1837
1838    @property
1839    def output_name(self) -> str:
1840        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1830    @property
1831    def quoted(self) -> bool:
1832        return bool(self.args.get("quoted"))
hashable_args: Any
1834    @property
1835    def hashable_args(self) -> t.Any:
1836        return (self.this, self.quoted)
output_name: str
1838    @property
1839    def output_name(self) -> str:
1840        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):
1844class Opclass(Expression):
1845    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1848class Index(Expression):
1849    arg_types = {
1850        "this": False,
1851        "table": False,
1852        "using": False,
1853        "where": False,
1854        "columns": False,
1855        "unique": False,
1856        "primary": False,
1857        "amp": False,  # teradata
1858        "include": False,
1859        "partition_by": False,  # teradata
1860    }
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):
1863class Insert(DDL, DML):
1864    arg_types = {
1865        "hint": False,
1866        "with": False,
1867        "this": True,
1868        "expression": False,
1869        "conflict": False,
1870        "returning": False,
1871        "overwrite": False,
1872        "exists": False,
1873        "partition": False,
1874        "alternative": False,
1875        "where": False,
1876        "ignore": False,
1877        "by_name": False,
1878    }
1879
1880    def with_(
1881        self,
1882        alias: ExpOrStr,
1883        as_: ExpOrStr,
1884        recursive: t.Optional[bool] = None,
1885        append: bool = True,
1886        dialect: DialectType = None,
1887        copy: bool = True,
1888        **opts,
1889    ) -> Insert:
1890        """
1891        Append to or set the common table expressions.
1892
1893        Example:
1894            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1895            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1896
1897        Args:
1898            alias: the SQL code string to parse as the table name.
1899                If an `Expression` instance is passed, this is used as-is.
1900            as_: the SQL code string to parse as the table expression.
1901                If an `Expression` instance is passed, it will be used as-is.
1902            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1903            append: if `True`, add to any existing expressions.
1904                Otherwise, this resets the expressions.
1905            dialect: the dialect used to parse the input expression.
1906            copy: if `False`, modify this expression instance in-place.
1907            opts: other options to use to parse the input expressions.
1908
1909        Returns:
1910            The modified expression.
1911        """
1912        return _apply_cte_builder(
1913            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1914        )
arg_types = {'hint': False, 'with': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1880    def with_(
1881        self,
1882        alias: ExpOrStr,
1883        as_: ExpOrStr,
1884        recursive: t.Optional[bool] = None,
1885        append: bool = True,
1886        dialect: DialectType = None,
1887        copy: bool = True,
1888        **opts,
1889    ) -> Insert:
1890        """
1891        Append to or set the common table expressions.
1892
1893        Example:
1894            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1895            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1896
1897        Args:
1898            alias: the SQL code string to parse as the table name.
1899                If an `Expression` instance is passed, this is used as-is.
1900            as_: the SQL code string to parse as the table expression.
1901                If an `Expression` instance is passed, it will be used as-is.
1902            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1903            append: if `True`, add to any existing expressions.
1904                Otherwise, this resets the expressions.
1905            dialect: the dialect used to parse the input expression.
1906            copy: if `False`, modify this expression instance in-place.
1907            opts: other options to use to parse the input expressions.
1908
1909        Returns:
1910            The modified expression.
1911        """
1912        return _apply_cte_builder(
1913            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1914        )

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):
1917class OnConflict(Expression):
1918    arg_types = {
1919        "duplicate": False,
1920        "expressions": False,
1921        "action": False,
1922        "conflict_keys": False,
1923        "constraint": False,
1924    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1927class Returning(Expression):
1928    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1932class Introducer(Expression):
1933    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1937class National(Expression):
1938    pass
key = 'national'
class LoadData(Expression):
1941class LoadData(Expression):
1942    arg_types = {
1943        "this": True,
1944        "local": False,
1945        "overwrite": False,
1946        "inpath": True,
1947        "partition": False,
1948        "input_format": False,
1949        "serde": False,
1950    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1953class Partition(Expression):
1954    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
1957class PartitionRange(Expression):
1958    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
1961class Fetch(Expression):
1962    arg_types = {
1963        "direction": False,
1964        "count": False,
1965        "percent": False,
1966        "with_ties": False,
1967    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1970class Group(Expression):
1971    arg_types = {
1972        "expressions": False,
1973        "grouping_sets": False,
1974        "cube": False,
1975        "rollup": False,
1976        "totals": False,
1977        "all": False,
1978    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1981class Lambda(Expression):
1982    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1985class Limit(Expression):
1986    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):
1989class Literal(Condition):
1990    arg_types = {"this": True, "is_string": True}
1991
1992    @property
1993    def hashable_args(self) -> t.Any:
1994        return (self.this, self.args.get("is_string"))
1995
1996    @classmethod
1997    def number(cls, number) -> Literal:
1998        return cls(this=str(number), is_string=False)
1999
2000    @classmethod
2001    def string(cls, string) -> Literal:
2002        return cls(this=str(string), is_string=True)
2003
2004    @property
2005    def output_name(self) -> str:
2006        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1992    @property
1993    def hashable_args(self) -> t.Any:
1994        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1996    @classmethod
1997    def number(cls, number) -> Literal:
1998        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2000    @classmethod
2001    def string(cls, string) -> Literal:
2002        return cls(this=str(string), is_string=True)
output_name: str
2004    @property
2005    def output_name(self) -> str:
2006        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):
2009class Join(Expression):
2010    arg_types = {
2011        "this": True,
2012        "on": False,
2013        "side": False,
2014        "kind": False,
2015        "using": False,
2016        "method": False,
2017        "global": False,
2018        "hint": False,
2019    }
2020
2021    @property
2022    def method(self) -> str:
2023        return self.text("method").upper()
2024
2025    @property
2026    def kind(self) -> str:
2027        return self.text("kind").upper()
2028
2029    @property
2030    def side(self) -> str:
2031        return self.text("side").upper()
2032
2033    @property
2034    def hint(self) -> str:
2035        return self.text("hint").upper()
2036
2037    @property
2038    def alias_or_name(self) -> str:
2039        return self.this.alias_or_name
2040
2041    def on(
2042        self,
2043        *expressions: t.Optional[ExpOrStr],
2044        append: bool = True,
2045        dialect: DialectType = None,
2046        copy: bool = True,
2047        **opts,
2048    ) -> Join:
2049        """
2050        Append to or set the ON expressions.
2051
2052        Example:
2053            >>> import sqlglot
2054            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2055            'JOIN x ON y = 1'
2056
2057        Args:
2058            *expressions: the SQL code strings to parse.
2059                If an `Expression` instance is passed, it will be used as-is.
2060                Multiple expressions are combined with an AND operator.
2061            append: if `True`, AND the new expressions to any existing expression.
2062                Otherwise, this resets the expression.
2063            dialect: the dialect used to parse the input expressions.
2064            copy: if `False`, modify this expression instance in-place.
2065            opts: other options to use to parse the input expressions.
2066
2067        Returns:
2068            The modified Join expression.
2069        """
2070        join = _apply_conjunction_builder(
2071            *expressions,
2072            instance=self,
2073            arg="on",
2074            append=append,
2075            dialect=dialect,
2076            copy=copy,
2077            **opts,
2078        )
2079
2080        if join.kind == "CROSS":
2081            join.set("kind", None)
2082
2083        return join
2084
2085    def using(
2086        self,
2087        *expressions: t.Optional[ExpOrStr],
2088        append: bool = True,
2089        dialect: DialectType = None,
2090        copy: bool = True,
2091        **opts,
2092    ) -> Join:
2093        """
2094        Append to or set the USING expressions.
2095
2096        Example:
2097            >>> import sqlglot
2098            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2099            'JOIN x USING (foo, bla)'
2100
2101        Args:
2102            *expressions: the SQL code strings to parse.
2103                If an `Expression` instance is passed, it will be used as-is.
2104            append: if `True`, concatenate the new expressions to the existing "using" list.
2105                Otherwise, this resets the expression.
2106            dialect: the dialect used to parse the input expressions.
2107            copy: if `False`, modify this expression instance in-place.
2108            opts: other options to use to parse the input expressions.
2109
2110        Returns:
2111            The modified Join expression.
2112        """
2113        join = _apply_list_builder(
2114            *expressions,
2115            instance=self,
2116            arg="using",
2117            append=append,
2118            dialect=dialect,
2119            copy=copy,
2120            **opts,
2121        )
2122
2123        if join.kind == "CROSS":
2124            join.set("kind", None)
2125
2126        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2021    @property
2022    def method(self) -> str:
2023        return self.text("method").upper()
kind: str
2025    @property
2026    def kind(self) -> str:
2027        return self.text("kind").upper()
side: str
2029    @property
2030    def side(self) -> str:
2031        return self.text("side").upper()
hint: str
2033    @property
2034    def hint(self) -> str:
2035        return self.text("hint").upper()
alias_or_name: str
2037    @property
2038    def alias_or_name(self) -> str:
2039        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:
2041    def on(
2042        self,
2043        *expressions: t.Optional[ExpOrStr],
2044        append: bool = True,
2045        dialect: DialectType = None,
2046        copy: bool = True,
2047        **opts,
2048    ) -> Join:
2049        """
2050        Append to or set the ON expressions.
2051
2052        Example:
2053            >>> import sqlglot
2054            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2055            'JOIN x ON y = 1'
2056
2057        Args:
2058            *expressions: the SQL code strings to parse.
2059                If an `Expression` instance is passed, it will be used as-is.
2060                Multiple expressions are combined with an AND operator.
2061            append: if `True`, AND the new expressions to any existing expression.
2062                Otherwise, this resets the expression.
2063            dialect: the dialect used to parse the input expressions.
2064            copy: if `False`, modify this expression instance in-place.
2065            opts: other options to use to parse the input expressions.
2066
2067        Returns:
2068            The modified Join expression.
2069        """
2070        join = _apply_conjunction_builder(
2071            *expressions,
2072            instance=self,
2073            arg="on",
2074            append=append,
2075            dialect=dialect,
2076            copy=copy,
2077            **opts,
2078        )
2079
2080        if join.kind == "CROSS":
2081            join.set("kind", None)
2082
2083        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:
2085    def using(
2086        self,
2087        *expressions: t.Optional[ExpOrStr],
2088        append: bool = True,
2089        dialect: DialectType = None,
2090        copy: bool = True,
2091        **opts,
2092    ) -> Join:
2093        """
2094        Append to or set the USING expressions.
2095
2096        Example:
2097            >>> import sqlglot
2098            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2099            'JOIN x USING (foo, bla)'
2100
2101        Args:
2102            *expressions: the SQL code strings to parse.
2103                If an `Expression` instance is passed, it will be used as-is.
2104            append: if `True`, concatenate the new expressions to the existing "using" list.
2105                Otherwise, this resets the expression.
2106            dialect: the dialect used to parse the input expressions.
2107            copy: if `False`, modify this expression instance in-place.
2108            opts: other options to use to parse the input expressions.
2109
2110        Returns:
2111            The modified Join expression.
2112        """
2113        join = _apply_list_builder(
2114            *expressions,
2115            instance=self,
2116            arg="using",
2117            append=append,
2118            dialect=dialect,
2119            copy=copy,
2120            **opts,
2121        )
2122
2123        if join.kind == "CROSS":
2124            join.set("kind", None)
2125
2126        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):
2129class Lateral(UDTF):
2130    arg_types = {
2131        "this": True,
2132        "view": False,
2133        "outer": False,
2134        "alias": False,
2135        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2136    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2139class MatchRecognize(Expression):
2140    arg_types = {
2141        "partition_by": False,
2142        "order": False,
2143        "measures": False,
2144        "rows": False,
2145        "after": False,
2146        "pattern": False,
2147        "define": False,
2148        "alias": False,
2149    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2154class Final(Expression):
2155    pass
key = 'final'
class Offset(Expression):
2158class Offset(Expression):
2159    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2162class Order(Expression):
2163    arg_types = {
2164        "this": False,
2165        "expressions": True,
2166        "interpolate": False,
2167        "siblings": False,
2168    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2172class WithFill(Expression):
2173    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2178class Cluster(Order):
2179    pass
key = 'cluster'
class Distribute(Order):
2182class Distribute(Order):
2183    pass
key = 'distribute'
class Sort(Order):
2186class Sort(Order):
2187    pass
key = 'sort'
class Ordered(Expression):
2190class Ordered(Expression):
2191    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):
2194class Property(Expression):
2195    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2198class AlgorithmProperty(Property):
2199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2202class AutoIncrementProperty(Property):
2203    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2207class AutoRefreshProperty(Property):
2208    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2211class BlockCompressionProperty(Property):
2212    arg_types = {
2213        "autotemp": False,
2214        "always": False,
2215        "default": False,
2216        "manual": False,
2217        "never": False,
2218    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2221class CharacterSetProperty(Property):
2222    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2225class ChecksumProperty(Property):
2226    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2229class CollateProperty(Property):
2230    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2233class CopyGrantsProperty(Property):
2234    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2237class DataBlocksizeProperty(Property):
2238    arg_types = {
2239        "size": False,
2240        "units": False,
2241        "minimum": False,
2242        "maximum": False,
2243        "default": False,
2244    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2247class DefinerProperty(Property):
2248    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2251class DistKeyProperty(Property):
2252    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2255class DistStyleProperty(Property):
2256    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2259class EngineProperty(Property):
2260    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2263class HeapProperty(Property):
2264    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2267class ToTableProperty(Property):
2268    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2271class ExecuteAsProperty(Property):
2272    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2275class ExternalProperty(Property):
2276    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2279class FallbackProperty(Property):
2280    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2283class FileFormatProperty(Property):
2284    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2287class FreespaceProperty(Property):
2288    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2291class GlobalProperty(Property):
2292    arg_types = {}
arg_types = {}
key = 'globalproperty'
class InheritsProperty(Property):
2295class InheritsProperty(Property):
2296    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2299class InputModelProperty(Property):
2300    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2303class OutputModelProperty(Property):
2304    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2307class IsolatedLoadingProperty(Property):
2308    arg_types = {
2309        "no": False,
2310        "concurrent": False,
2311        "for_all": False,
2312        "for_insert": False,
2313        "for_none": False,
2314    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2317class JournalProperty(Property):
2318    arg_types = {
2319        "no": False,
2320        "dual": False,
2321        "before": False,
2322        "local": False,
2323        "after": False,
2324    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2327class LanguageProperty(Property):
2328    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2332class ClusteredByProperty(Property):
2333    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2336class DictProperty(Property):
2337    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2340class DictSubProperty(Property):
2341    pass
key = 'dictsubproperty'
class DictRange(Property):
2344class DictRange(Property):
2345    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2350class OnCluster(Property):
2351    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2354class LikeProperty(Property):
2355    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2358class LocationProperty(Property):
2359    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2362class LockProperty(Property):
2363    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2366class LockingProperty(Property):
2367    arg_types = {
2368        "this": False,
2369        "kind": True,
2370        "for_or_in": False,
2371        "lock_type": True,
2372        "override": False,
2373    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2376class LogProperty(Property):
2377    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2380class MaterializedProperty(Property):
2381    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2384class MergeBlockRatioProperty(Property):
2385    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):
2388class NoPrimaryIndexProperty(Property):
2389    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2392class OnProperty(Property):
2393    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2396class OnCommitProperty(Property):
2397    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2400class PartitionedByProperty(Property):
2401    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2405class PartitionBoundSpec(Expression):
2406    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2407    arg_types = {
2408        "this": False,
2409        "expression": False,
2410        "from_expressions": False,
2411        "to_expressions": False,
2412    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2415class PartitionedOfProperty(Property):
2416    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2417    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2420class RemoteWithConnectionModelProperty(Property):
2421    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2424class ReturnsProperty(Property):
2425    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2428class RowFormatProperty(Property):
2429    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2432class RowFormatDelimitedProperty(Property):
2433    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2434    arg_types = {
2435        "fields": False,
2436        "escaped": False,
2437        "collection_items": False,
2438        "map_keys": False,
2439        "lines": False,
2440        "null": False,
2441        "serde": False,
2442    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2445class RowFormatSerdeProperty(Property):
2446    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2450class QueryTransform(Expression):
2451    arg_types = {
2452        "expressions": True,
2453        "command_script": True,
2454        "schema": False,
2455        "row_format_before": False,
2456        "record_writer": False,
2457        "row_format_after": False,
2458        "record_reader": False,
2459    }
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):
2462class SampleProperty(Property):
2463    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2466class SchemaCommentProperty(Property):
2467    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2470class SerdeProperties(Property):
2471    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2474class SetProperty(Property):
2475    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2478class SharingProperty(Property):
2479    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2482class SetConfigProperty(Property):
2483    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2486class SettingsProperty(Property):
2487    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2490class SortKeyProperty(Property):
2491    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2494class SqlReadWriteProperty(Property):
2495    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2498class SqlSecurityProperty(Property):
2499    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2502class StabilityProperty(Property):
2503    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2506class TemporaryProperty(Property):
2507    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2510class TransformModelProperty(Property):
2511    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2514class TransientProperty(Property):
2515    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2518class UnloggedProperty(Property):
2519    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class VolatileProperty(Property):
2522class VolatileProperty(Property):
2523    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2526class WithDataProperty(Property):
2527    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2530class WithJournalTableProperty(Property):
2531    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2534class WithSystemVersioningProperty(Property):
2535    # this -> history table name, expression -> data consistency check
2536    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2539class Properties(Expression):
2540    arg_types = {"expressions": True}
2541
2542    NAME_TO_PROPERTY = {
2543        "ALGORITHM": AlgorithmProperty,
2544        "AUTO_INCREMENT": AutoIncrementProperty,
2545        "CHARACTER SET": CharacterSetProperty,
2546        "CLUSTERED_BY": ClusteredByProperty,
2547        "COLLATE": CollateProperty,
2548        "COMMENT": SchemaCommentProperty,
2549        "DEFINER": DefinerProperty,
2550        "DISTKEY": DistKeyProperty,
2551        "DISTSTYLE": DistStyleProperty,
2552        "ENGINE": EngineProperty,
2553        "EXECUTE AS": ExecuteAsProperty,
2554        "FORMAT": FileFormatProperty,
2555        "LANGUAGE": LanguageProperty,
2556        "LOCATION": LocationProperty,
2557        "LOCK": LockProperty,
2558        "PARTITIONED_BY": PartitionedByProperty,
2559        "RETURNS": ReturnsProperty,
2560        "ROW_FORMAT": RowFormatProperty,
2561        "SORTKEY": SortKeyProperty,
2562    }
2563
2564    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2565
2566    # CREATE property locations
2567    # Form: schema specified
2568    #   create [POST_CREATE]
2569    #     table a [POST_NAME]
2570    #     (b int) [POST_SCHEMA]
2571    #     with ([POST_WITH])
2572    #     index (b) [POST_INDEX]
2573    #
2574    # Form: alias selection
2575    #   create [POST_CREATE]
2576    #     table a [POST_NAME]
2577    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2578    #     index (c) [POST_INDEX]
2579    class Location(AutoName):
2580        POST_CREATE = auto()
2581        POST_NAME = auto()
2582        POST_SCHEMA = auto()
2583        POST_WITH = auto()
2584        POST_ALIAS = auto()
2585        POST_EXPRESSION = auto()
2586        POST_INDEX = auto()
2587        UNSUPPORTED = auto()
2588
2589    @classmethod
2590    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2591        expressions = []
2592        for key, value in properties_dict.items():
2593            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2594            if property_cls:
2595                expressions.append(property_cls(this=convert(value)))
2596            else:
2597                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2598
2599        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:
2589    @classmethod
2590    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2591        expressions = []
2592        for key, value in properties_dict.items():
2593            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2594            if property_cls:
2595                expressions.append(property_cls(this=convert(value)))
2596            else:
2597                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2598
2599        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2579    class Location(AutoName):
2580        POST_CREATE = auto()
2581        POST_NAME = auto()
2582        POST_SCHEMA = auto()
2583        POST_WITH = auto()
2584        POST_ALIAS = auto()
2585        POST_EXPRESSION = auto()
2586        POST_INDEX = auto()
2587        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):
2602class Qualify(Expression):
2603    pass
key = 'qualify'
class InputOutputFormat(Expression):
2606class InputOutputFormat(Expression):
2607    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2611class Return(Expression):
2612    pass
key = 'return'
class Reference(Expression):
2615class Reference(Expression):
2616    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2619class Tuple(Expression):
2620    arg_types = {"expressions": False}
2621
2622    def isin(
2623        self,
2624        *expressions: t.Any,
2625        query: t.Optional[ExpOrStr] = None,
2626        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2627        copy: bool = True,
2628        **opts,
2629    ) -> In:
2630        return In(
2631            this=maybe_copy(self, copy),
2632            expressions=[convert(e, copy=copy) for e in expressions],
2633            query=maybe_parse(query, copy=copy, **opts) if query else None,
2634            unnest=(
2635                Unnest(
2636                    expressions=[
2637                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2638                        for e in ensure_list(unnest)
2639                    ]
2640                )
2641                if unnest
2642                else None
2643            ),
2644        )
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:
2622    def isin(
2623        self,
2624        *expressions: t.Any,
2625        query: t.Optional[ExpOrStr] = None,
2626        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2627        copy: bool = True,
2628        **opts,
2629    ) -> In:
2630        return In(
2631            this=maybe_copy(self, copy),
2632            expressions=[convert(e, copy=copy) for e in expressions],
2633            query=maybe_parse(query, copy=copy, **opts) if query else None,
2634            unnest=(
2635                Unnest(
2636                    expressions=[
2637                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2638                        for e in ensure_list(unnest)
2639                    ]
2640                )
2641                if unnest
2642                else None
2643            ),
2644        )
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):
2675class QueryOption(Expression):
2676    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2680class WithTableHint(Expression):
2681    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2685class IndexTableHint(Expression):
2686    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2690class HistoricalData(Expression):
2691    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2694class Table(Expression):
2695    arg_types = {
2696        "this": False,
2697        "alias": False,
2698        "db": False,
2699        "catalog": False,
2700        "laterals": False,
2701        "joins": False,
2702        "pivots": False,
2703        "hints": False,
2704        "system_time": False,
2705        "version": False,
2706        "format": False,
2707        "pattern": False,
2708        "ordinality": False,
2709        "when": False,
2710        "only": False,
2711    }
2712
2713    @property
2714    def name(self) -> str:
2715        if isinstance(self.this, Func):
2716            return ""
2717        return self.this.name
2718
2719    @property
2720    def db(self) -> str:
2721        return self.text("db")
2722
2723    @property
2724    def catalog(self) -> str:
2725        return self.text("catalog")
2726
2727    @property
2728    def selects(self) -> t.List[Expression]:
2729        return []
2730
2731    @property
2732    def named_selects(self) -> t.List[str]:
2733        return []
2734
2735    @property
2736    def parts(self) -> t.List[Expression]:
2737        """Return the parts of a table in order catalog, db, table."""
2738        parts: t.List[Expression] = []
2739
2740        for arg in ("catalog", "db", "this"):
2741            part = self.args.get(arg)
2742
2743            if isinstance(part, Dot):
2744                parts.extend(part.flatten())
2745            elif isinstance(part, Expression):
2746                parts.append(part)
2747
2748        return parts
2749
2750    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2751        parts = self.parts
2752        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2753        alias = self.args.get("alias")
2754        if alias:
2755            col = alias_(col, alias.this, copy=copy)
2756        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
2713    @property
2714    def name(self) -> str:
2715        if isinstance(self.this, Func):
2716            return ""
2717        return self.this.name
db: str
2719    @property
2720    def db(self) -> str:
2721        return self.text("db")
catalog: str
2723    @property
2724    def catalog(self) -> str:
2725        return self.text("catalog")
selects: List[Expression]
2727    @property
2728    def selects(self) -> t.List[Expression]:
2729        return []
named_selects: List[str]
2731    @property
2732    def named_selects(self) -> t.List[str]:
2733        return []
parts: List[Expression]
2735    @property
2736    def parts(self) -> t.List[Expression]:
2737        """Return the parts of a table in order catalog, db, table."""
2738        parts: t.List[Expression] = []
2739
2740        for arg in ("catalog", "db", "this"):
2741            part = self.args.get(arg)
2742
2743            if isinstance(part, Dot):
2744                parts.extend(part.flatten())
2745            elif isinstance(part, Expression):
2746                parts.append(part)
2747
2748        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2750    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2751        parts = self.parts
2752        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2753        alias = self.args.get("alias")
2754        if alias:
2755            col = alias_(col, alias.this, copy=copy)
2756        return col
key = 'table'
class Union(Query):
2759class Union(Query):
2760    arg_types = {
2761        "with": False,
2762        "this": True,
2763        "expression": True,
2764        "distinct": False,
2765        "by_name": False,
2766        **QUERY_MODIFIERS,
2767    }
2768
2769    def select(
2770        self,
2771        *expressions: t.Optional[ExpOrStr],
2772        append: bool = True,
2773        dialect: DialectType = None,
2774        copy: bool = True,
2775        **opts,
2776    ) -> Union:
2777        this = maybe_copy(self, copy)
2778        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2779        this.expression.unnest().select(
2780            *expressions, append=append, dialect=dialect, copy=False, **opts
2781        )
2782        return this
2783
2784    @property
2785    def named_selects(self) -> t.List[str]:
2786        return self.this.unnest().named_selects
2787
2788    @property
2789    def is_star(self) -> bool:
2790        return self.this.is_star or self.expression.is_star
2791
2792    @property
2793    def selects(self) -> t.List[Expression]:
2794        return self.this.unnest().selects
2795
2796    @property
2797    def left(self) -> Expression:
2798        return self.this
2799
2800    @property
2801    def right(self) -> Expression:
2802        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:
2769    def select(
2770        self,
2771        *expressions: t.Optional[ExpOrStr],
2772        append: bool = True,
2773        dialect: DialectType = None,
2774        copy: bool = True,
2775        **opts,
2776    ) -> Union:
2777        this = maybe_copy(self, copy)
2778        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2779        this.expression.unnest().select(
2780            *expressions, append=append, dialect=dialect, copy=False, **opts
2781        )
2782        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]
2784    @property
2785    def named_selects(self) -> t.List[str]:
2786        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2788    @property
2789    def is_star(self) -> bool:
2790        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2792    @property
2793    def selects(self) -> t.List[Expression]:
2794        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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:
3082    def limit(
3083        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3084    ) -> Select:
3085        return _apply_builder(
3086            expression=expression,
3087            instance=self,
3088            arg="limit",
3089            into=Limit,
3090            prefix="LIMIT",
3091            dialect=dialect,
3092            copy=copy,
3093            into_arg="expression",
3094            **opts,
3095        )

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:
3097    def offset(
3098        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3099    ) -> Select:
3100        """
3101        Set the OFFSET expression.
3102
3103        Example:
3104            >>> Select().from_("tbl").select("x").offset(10).sql()
3105            'SELECT x FROM tbl OFFSET 10'
3106
3107        Args:
3108            expression: the SQL code string to parse.
3109                This can also be an integer.
3110                If a `Offset` instance is passed, this is used as-is.
3111                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3112            dialect: the dialect used to parse the input expression.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            The modified Select expression.
3118        """
3119        return _apply_builder(
3120            expression=expression,
3121            instance=self,
3122            arg="offset",
3123            into=Offset,
3124            prefix="OFFSET",
3125            dialect=dialect,
3126            copy=copy,
3127            into_arg="expression",
3128            **opts,
3129        )

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:
3131    def select(
3132        self,
3133        *expressions: t.Optional[ExpOrStr],
3134        append: bool = True,
3135        dialect: DialectType = None,
3136        copy: bool = True,
3137        **opts,
3138    ) -> Select:
3139        return _apply_list_builder(
3140            *expressions,
3141            instance=self,
3142            arg="expressions",
3143            append=append,
3144            dialect=dialect,
3145            into=Expression,
3146            copy=copy,
3147            **opts,
3148        )

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:
3150    def lateral(
3151        self,
3152        *expressions: t.Optional[ExpOrStr],
3153        append: bool = True,
3154        dialect: DialectType = None,
3155        copy: bool = True,
3156        **opts,
3157    ) -> Select:
3158        """
3159        Append to or set the LATERAL expressions.
3160
3161        Example:
3162            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3163            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3164
3165        Args:
3166            *expressions: the SQL code strings to parse.
3167                If an `Expression` instance is passed, it will be used as-is.
3168            append: if `True`, add to any existing expressions.
3169                Otherwise, this resets the expressions.
3170            dialect: the dialect used to parse the input expressions.
3171            copy: if `False`, modify this expression instance in-place.
3172            opts: other options to use to parse the input expressions.
3173
3174        Returns:
3175            The modified Select expression.
3176        """
3177        return _apply_list_builder(
3178            *expressions,
3179            instance=self,
3180            arg="laterals",
3181            append=append,
3182            into=Lateral,
3183            prefix="LATERAL VIEW",
3184            dialect=dialect,
3185            copy=copy,
3186            **opts,
3187        )

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:
3189    def join(
3190        self,
3191        expression: ExpOrStr,
3192        on: t.Optional[ExpOrStr] = None,
3193        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3194        append: bool = True,
3195        join_type: t.Optional[str] = None,
3196        join_alias: t.Optional[Identifier | str] = None,
3197        dialect: DialectType = None,
3198        copy: bool = True,
3199        **opts,
3200    ) -> Select:
3201        """
3202        Append to or set the JOIN expressions.
3203
3204        Example:
3205            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3206            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3207
3208            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3209            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3210
3211            Use `join_type` to change the type of join:
3212
3213            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3214            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3215
3216        Args:
3217            expression: the SQL code string to parse.
3218                If an `Expression` instance is passed, it will be used as-is.
3219            on: optionally specify the join "on" criteria as a SQL string.
3220                If an `Expression` instance is passed, it will be used as-is.
3221            using: optionally specify the join "using" criteria as a SQL string.
3222                If an `Expression` instance is passed, it will be used as-is.
3223            append: if `True`, add to any existing expressions.
3224                Otherwise, this resets the expressions.
3225            join_type: if set, alter the parsed join type.
3226            join_alias: an optional alias for the joined source.
3227            dialect: the dialect used to parse the input expressions.
3228            copy: if `False`, modify this expression instance in-place.
3229            opts: other options to use to parse the input expressions.
3230
3231        Returns:
3232            Select: the modified expression.
3233        """
3234        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3235
3236        try:
3237            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3238        except ParseError:
3239            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3240
3241        join = expression if isinstance(expression, Join) else Join(this=expression)
3242
3243        if isinstance(join.this, Select):
3244            join.this.replace(join.this.subquery())
3245
3246        if join_type:
3247            method: t.Optional[Token]
3248            side: t.Optional[Token]
3249            kind: t.Optional[Token]
3250
3251            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3252
3253            if method:
3254                join.set("method", method.text)
3255            if side:
3256                join.set("side", side.text)
3257            if kind:
3258                join.set("kind", kind.text)
3259
3260        if on:
3261            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3262            join.set("on", on)
3263
3264        if using:
3265            join = _apply_list_builder(
3266                *ensure_list(using),
3267                instance=join,
3268                arg="using",
3269                append=append,
3270                copy=copy,
3271                into=Identifier,
3272                **opts,
3273            )
3274
3275        if join_alias:
3276            join.set("this", alias_(join.this, join_alias, table=True))
3277
3278        return _apply_list_builder(
3279            join,
3280            instance=self,
3281            arg="joins",
3282            append=append,
3283            copy=copy,
3284            **opts,
3285        )

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

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:
3326    def having(
3327        self,
3328        *expressions: t.Optional[ExpOrStr],
3329        append: bool = True,
3330        dialect: DialectType = None,
3331        copy: bool = True,
3332        **opts,
3333    ) -> Select:
3334        """
3335        Append to or set the HAVING expressions.
3336
3337        Example:
3338            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3339            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3340
3341        Args:
3342            *expressions: the SQL code strings to parse.
3343                If an `Expression` instance is passed, it will be used as-is.
3344                Multiple expressions are combined with an AND operator.
3345            append: if `True`, AND the new expressions to any existing expression.
3346                Otherwise, this resets the expression.
3347            dialect: the dialect used to parse the input expressions.
3348            copy: if `False`, modify this expression instance in-place.
3349            opts: other options to use to parse the input expressions.
3350
3351        Returns:
3352            The modified Select expression.
3353        """
3354        return _apply_conjunction_builder(
3355            *expressions,
3356            instance=self,
3357            arg="having",
3358            append=append,
3359            into=Having,
3360            dialect=dialect,
3361            copy=copy,
3362            **opts,
3363        )

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:
3365    def window(
3366        self,
3367        *expressions: t.Optional[ExpOrStr],
3368        append: bool = True,
3369        dialect: DialectType = None,
3370        copy: bool = True,
3371        **opts,
3372    ) -> Select:
3373        return _apply_list_builder(
3374            *expressions,
3375            instance=self,
3376            arg="windows",
3377            append=append,
3378            into=Window,
3379            dialect=dialect,
3380            copy=copy,
3381            **opts,
3382        )
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:
3384    def qualify(
3385        self,
3386        *expressions: t.Optional[ExpOrStr],
3387        append: bool = True,
3388        dialect: DialectType = None,
3389        copy: bool = True,
3390        **opts,
3391    ) -> Select:
3392        return _apply_conjunction_builder(
3393            *expressions,
3394            instance=self,
3395            arg="qualify",
3396            append=append,
3397            into=Qualify,
3398            dialect=dialect,
3399            copy=copy,
3400            **opts,
3401        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3403    def distinct(
3404        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3405    ) -> Select:
3406        """
3407        Set the OFFSET expression.
3408
3409        Example:
3410            >>> Select().from_("tbl").select("x").distinct().sql()
3411            'SELECT DISTINCT x FROM tbl'
3412
3413        Args:
3414            ons: the expressions to distinct on
3415            distinct: whether the Select should be distinct
3416            copy: if `False`, modify this expression instance in-place.
3417
3418        Returns:
3419            Select: the modified expression.
3420        """
3421        instance = maybe_copy(self, copy)
3422        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3423        instance.set("distinct", Distinct(on=on) if distinct else None)
3424        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:
3426    def ctas(
3427        self,
3428        table: ExpOrStr,
3429        properties: t.Optional[t.Dict] = None,
3430        dialect: DialectType = None,
3431        copy: bool = True,
3432        **opts,
3433    ) -> Create:
3434        """
3435        Convert this expression to a CREATE TABLE AS statement.
3436
3437        Example:
3438            >>> Select().select("*").from_("tbl").ctas("x").sql()
3439            'CREATE TABLE x AS SELECT * FROM tbl'
3440
3441        Args:
3442            table: the SQL code string to parse as the table name.
3443                If another `Expression` instance is passed, it will be used as-is.
3444            properties: an optional mapping of table properties
3445            dialect: the dialect used to parse the input table.
3446            copy: if `False`, modify this expression instance in-place.
3447            opts: other options to use to parse the input table.
3448
3449        Returns:
3450            The new Create expression.
3451        """
3452        instance = maybe_copy(self, copy)
3453        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3454
3455        properties_expression = None
3456        if properties:
3457            properties_expression = Properties.from_dict(properties)
3458
3459        return Create(
3460            this=table_expression,
3461            kind="TABLE",
3462            expression=instance,
3463            properties=properties_expression,
3464        )

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:
3466    def lock(self, update: bool = True, copy: bool = True) -> Select:
3467        """
3468        Set the locking read mode for this expression.
3469
3470        Examples:
3471            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3472            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3473
3474            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3475            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3476
3477        Args:
3478            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3479            copy: if `False`, modify this expression instance in-place.
3480
3481        Returns:
3482            The modified expression.
3483        """
3484        inst = maybe_copy(self, copy)
3485        inst.set("locks", [Lock(update=update)])
3486
3487        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:
3489    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3490        """
3491        Set hints for this expression.
3492
3493        Examples:
3494            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3495            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3496
3497        Args:
3498            hints: The SQL code strings to parse as the hints.
3499                If an `Expression` instance is passed, it will be used as-is.
3500            dialect: The dialect used to parse the hints.
3501            copy: If `False`, modify this expression instance in-place.
3502
3503        Returns:
3504            The modified expression.
3505        """
3506        inst = maybe_copy(self, copy)
3507        inst.set(
3508            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3509        )
3510
3511        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]
3513    @property
3514    def named_selects(self) -> t.List[str]:
3515        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
3517    @property
3518    def is_star(self) -> bool:
3519        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3521    @property
3522    def selects(self) -> t.List[Expression]:
3523        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3529class Subquery(DerivedTable, Query):
3530    arg_types = {
3531        "this": True,
3532        "alias": False,
3533        "with": False,
3534        **QUERY_MODIFIERS,
3535    }
3536
3537    def unnest(self):
3538        """Returns the first non subquery."""
3539        expression = self
3540        while isinstance(expression, Subquery):
3541            expression = expression.this
3542        return expression
3543
3544    def unwrap(self) -> Subquery:
3545        expression = self
3546        while expression.same_parent and expression.is_wrapper:
3547            expression = t.cast(Subquery, expression.parent)
3548        return expression
3549
3550    def select(
3551        self,
3552        *expressions: t.Optional[ExpOrStr],
3553        append: bool = True,
3554        dialect: DialectType = None,
3555        copy: bool = True,
3556        **opts,
3557    ) -> Subquery:
3558        this = maybe_copy(self, copy)
3559        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3560        return this
3561
3562    @property
3563    def is_wrapper(self) -> bool:
3564        """
3565        Whether this Subquery acts as a simple wrapper around another expression.
3566
3567        SELECT * FROM (((SELECT * FROM t)))
3568                      ^
3569                      This corresponds to a "wrapper" Subquery node
3570        """
3571        return all(v is None for k, v in self.args.items() if k != "this")
3572
3573    @property
3574    def is_star(self) -> bool:
3575        return self.this.is_star
3576
3577    @property
3578    def output_name(self) -> str:
3579        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):
3537    def unnest(self):
3538        """Returns the first non subquery."""
3539        expression = self
3540        while isinstance(expression, Subquery):
3541            expression = expression.this
3542        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3544    def unwrap(self) -> Subquery:
3545        expression = self
3546        while expression.same_parent and expression.is_wrapper:
3547            expression = t.cast(Subquery, expression.parent)
3548        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:
3550    def select(
3551        self,
3552        *expressions: t.Optional[ExpOrStr],
3553        append: bool = True,
3554        dialect: DialectType = None,
3555        copy: bool = True,
3556        **opts,
3557    ) -> Subquery:
3558        this = maybe_copy(self, copy)
3559        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3560        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
3562    @property
3563    def is_wrapper(self) -> bool:
3564        """
3565        Whether this Subquery acts as a simple wrapper around another expression.
3566
3567        SELECT * FROM (((SELECT * FROM t)))
3568                      ^
3569                      This corresponds to a "wrapper" Subquery node
3570        """
3571        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
3573    @property
3574    def is_star(self) -> bool:
3575        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3577    @property
3578    def output_name(self) -> str:
3579        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):
3582class TableSample(Expression):
3583    arg_types = {
3584        "this": False,
3585        "expressions": False,
3586        "method": False,
3587        "bucket_numerator": False,
3588        "bucket_denominator": False,
3589        "bucket_field": False,
3590        "percent": False,
3591        "rows": False,
3592        "size": False,
3593        "seed": False,
3594    }
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):
3597class Tag(Expression):
3598    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3599
3600    arg_types = {
3601        "this": False,
3602        "prefix": False,
3603        "postfix": False,
3604    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3609class Pivot(Expression):
3610    arg_types = {
3611        "this": False,
3612        "alias": False,
3613        "expressions": False,
3614        "field": False,
3615        "unpivot": False,
3616        "using": False,
3617        "group": False,
3618        "columns": False,
3619        "include_nulls": False,
3620    }
3621
3622    @property
3623    def unpivot(self) -> bool:
3624        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
3622    @property
3623    def unpivot(self) -> bool:
3624        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3627class Window(Condition):
3628    arg_types = {
3629        "this": True,
3630        "partition_by": False,
3631        "order": False,
3632        "spec": False,
3633        "alias": False,
3634        "over": False,
3635        "first": False,
3636    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3639class WindowSpec(Expression):
3640    arg_types = {
3641        "kind": False,
3642        "start": False,
3643        "start_side": False,
3644        "end": False,
3645        "end_side": False,
3646    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3649class PreWhere(Expression):
3650    pass
key = 'prewhere'
class Where(Expression):
3653class Where(Expression):
3654    pass
key = 'where'
class Star(Expression):
3657class Star(Expression):
3658    arg_types = {"except": False, "replace": False}
3659
3660    @property
3661    def name(self) -> str:
3662        return "*"
3663
3664    @property
3665    def output_name(self) -> str:
3666        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3660    @property
3661    def name(self) -> str:
3662        return "*"
output_name: str
3664    @property
3665    def output_name(self) -> str:
3666        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):
3669class Parameter(Condition):
3670    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3673class SessionParameter(Condition):
3674    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3677class Placeholder(Condition):
3678    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3681class Null(Condition):
3682    arg_types: t.Dict[str, t.Any] = {}
3683
3684    @property
3685    def name(self) -> str:
3686        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3684    @property
3685    def name(self) -> str:
3686        return "NULL"
key = 'null'
class Boolean(Condition):
3689class Boolean(Condition):
3690    pass
key = 'boolean'
class DataTypeParam(Expression):
3693class DataTypeParam(Expression):
3694    arg_types = {"this": True, "expression": False}
3695
3696    @property
3697    def name(self) -> str:
3698        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3696    @property
3697    def name(self) -> str:
3698        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3701class DataType(Expression):
3702    arg_types = {
3703        "this": True,
3704        "expressions": False,
3705        "nested": False,
3706        "values": False,
3707        "prefix": False,
3708        "kind": False,
3709    }
3710
3711    class Type(AutoName):
3712        ARRAY = auto()
3713        AGGREGATEFUNCTION = auto()
3714        SIMPLEAGGREGATEFUNCTION = auto()
3715        BIGDECIMAL = auto()
3716        BIGINT = auto()
3717        BIGSERIAL = auto()
3718        BINARY = auto()
3719        BIT = auto()
3720        BOOLEAN = auto()
3721        BPCHAR = auto()
3722        CHAR = auto()
3723        DATE = auto()
3724        DATE32 = auto()
3725        DATEMULTIRANGE = auto()
3726        DATERANGE = auto()
3727        DATETIME = auto()
3728        DATETIME64 = auto()
3729        DECIMAL = auto()
3730        DOUBLE = auto()
3731        ENUM = auto()
3732        ENUM8 = auto()
3733        ENUM16 = auto()
3734        FIXEDSTRING = auto()
3735        FLOAT = auto()
3736        GEOGRAPHY = auto()
3737        GEOMETRY = auto()
3738        HLLSKETCH = auto()
3739        HSTORE = auto()
3740        IMAGE = auto()
3741        INET = auto()
3742        INT = auto()
3743        INT128 = auto()
3744        INT256 = auto()
3745        INT4MULTIRANGE = auto()
3746        INT4RANGE = auto()
3747        INT8MULTIRANGE = auto()
3748        INT8RANGE = auto()
3749        INTERVAL = auto()
3750        IPADDRESS = auto()
3751        IPPREFIX = auto()
3752        IPV4 = auto()
3753        IPV6 = auto()
3754        JSON = auto()
3755        JSONB = auto()
3756        LONGBLOB = auto()
3757        LONGTEXT = auto()
3758        LOWCARDINALITY = auto()
3759        MAP = auto()
3760        MEDIUMBLOB = auto()
3761        MEDIUMINT = auto()
3762        MEDIUMTEXT = auto()
3763        MONEY = auto()
3764        NCHAR = auto()
3765        NESTED = auto()
3766        NULL = auto()
3767        NULLABLE = auto()
3768        NUMMULTIRANGE = auto()
3769        NUMRANGE = auto()
3770        NVARCHAR = auto()
3771        OBJECT = auto()
3772        ROWVERSION = auto()
3773        SERIAL = auto()
3774        SET = auto()
3775        SMALLINT = auto()
3776        SMALLMONEY = auto()
3777        SMALLSERIAL = auto()
3778        STRUCT = auto()
3779        SUPER = auto()
3780        TEXT = auto()
3781        TINYBLOB = auto()
3782        TINYTEXT = auto()
3783        TIME = auto()
3784        TIMETZ = auto()
3785        TIMESTAMP = auto()
3786        TIMESTAMPLTZ = auto()
3787        TIMESTAMPTZ = auto()
3788        TIMESTAMP_S = auto()
3789        TIMESTAMP_MS = auto()
3790        TIMESTAMP_NS = auto()
3791        TINYINT = auto()
3792        TSMULTIRANGE = auto()
3793        TSRANGE = auto()
3794        TSTZMULTIRANGE = auto()
3795        TSTZRANGE = auto()
3796        UBIGINT = auto()
3797        UINT = auto()
3798        UINT128 = auto()
3799        UINT256 = auto()
3800        UMEDIUMINT = auto()
3801        UDECIMAL = auto()
3802        UNIQUEIDENTIFIER = auto()
3803        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3804        USERDEFINED = "USER-DEFINED"
3805        USMALLINT = auto()
3806        UTINYINT = auto()
3807        UUID = auto()
3808        VARBINARY = auto()
3809        VARCHAR = auto()
3810        VARIANT = auto()
3811        XML = auto()
3812        YEAR = auto()
3813
3814    TEXT_TYPES = {
3815        Type.CHAR,
3816        Type.NCHAR,
3817        Type.NVARCHAR,
3818        Type.TEXT,
3819        Type.VARCHAR,
3820    }
3821
3822    INTEGER_TYPES = {
3823        Type.BIGINT,
3824        Type.BIT,
3825        Type.INT,
3826        Type.INT128,
3827        Type.INT256,
3828        Type.MEDIUMINT,
3829        Type.SMALLINT,
3830        Type.TINYINT,
3831        Type.UBIGINT,
3832        Type.UINT,
3833        Type.UINT128,
3834        Type.UINT256,
3835        Type.UMEDIUMINT,
3836        Type.USMALLINT,
3837        Type.UTINYINT,
3838    }
3839
3840    FLOAT_TYPES = {
3841        Type.DOUBLE,
3842        Type.FLOAT,
3843    }
3844
3845    REAL_TYPES = {
3846        *FLOAT_TYPES,
3847        Type.BIGDECIMAL,
3848        Type.DECIMAL,
3849        Type.MONEY,
3850        Type.SMALLMONEY,
3851        Type.UDECIMAL,
3852    }
3853
3854    NUMERIC_TYPES = {
3855        *INTEGER_TYPES,
3856        *REAL_TYPES,
3857    }
3858
3859    TEMPORAL_TYPES = {
3860        Type.DATE,
3861        Type.DATE32,
3862        Type.DATETIME,
3863        Type.DATETIME64,
3864        Type.TIME,
3865        Type.TIMESTAMP,
3866        Type.TIMESTAMPLTZ,
3867        Type.TIMESTAMPTZ,
3868        Type.TIMESTAMP_MS,
3869        Type.TIMESTAMP_NS,
3870        Type.TIMESTAMP_S,
3871        Type.TIMETZ,
3872    }
3873
3874    @classmethod
3875    def build(
3876        cls,
3877        dtype: DATA_TYPE,
3878        dialect: DialectType = None,
3879        udt: bool = False,
3880        copy: bool = True,
3881        **kwargs,
3882    ) -> DataType:
3883        """
3884        Constructs a DataType object.
3885
3886        Args:
3887            dtype: the data type of interest.
3888            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3889            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3890                DataType, thus creating a user-defined type.
3891            copy: whether to copy the data type.
3892            kwargs: additional arguments to pass in the constructor of DataType.
3893
3894        Returns:
3895            The constructed DataType object.
3896        """
3897        from sqlglot import parse_one
3898
3899        if isinstance(dtype, str):
3900            if dtype.upper() == "UNKNOWN":
3901                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3902
3903            try:
3904                data_type_exp = parse_one(
3905                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3906                )
3907            except ParseError:
3908                if udt:
3909                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3910                raise
3911        elif isinstance(dtype, DataType.Type):
3912            data_type_exp = DataType(this=dtype)
3913        elif isinstance(dtype, DataType):
3914            return maybe_copy(dtype, copy)
3915        else:
3916            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3917
3918        return DataType(**{**data_type_exp.args, **kwargs})
3919
3920    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3921        """
3922        Checks whether this DataType matches one of the provided data types. Nested types or precision
3923        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3924
3925        Args:
3926            dtypes: the data types to compare this DataType to.
3927
3928        Returns:
3929            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3930        """
3931        for dtype in dtypes:
3932            other = DataType.build(dtype, copy=False, udt=True)
3933
3934            if (
3935                other.expressions
3936                or self.this == DataType.Type.USERDEFINED
3937                or other.this == DataType.Type.USERDEFINED
3938            ):
3939                matches = self == other
3940            else:
3941                matches = self.this == other.this
3942
3943            if matches:
3944                return True
3945        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
NUMERIC_TYPES = {<Type.INT256: 'INT256'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGINT: 'BIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.MONEY: 'MONEY'>, <Type.INT: 'INT'>, <Type.UINT256: 'UINT256'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.BIT: 'BIT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UBIGINT: 'UBIGINT'>}
TEMPORAL_TYPES = {<Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
@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:
3874    @classmethod
3875    def build(
3876        cls,
3877        dtype: DATA_TYPE,
3878        dialect: DialectType = None,
3879        udt: bool = False,
3880        copy: bool = True,
3881        **kwargs,
3882    ) -> DataType:
3883        """
3884        Constructs a DataType object.
3885
3886        Args:
3887            dtype: the data type of interest.
3888            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3889            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3890                DataType, thus creating a user-defined type.
3891            copy: whether to copy the data type.
3892            kwargs: additional arguments to pass in the constructor of DataType.
3893
3894        Returns:
3895            The constructed DataType object.
3896        """
3897        from sqlglot import parse_one
3898
3899        if isinstance(dtype, str):
3900            if dtype.upper() == "UNKNOWN":
3901                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3902
3903            try:
3904                data_type_exp = parse_one(
3905                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3906                )
3907            except ParseError:
3908                if udt:
3909                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3910                raise
3911        elif isinstance(dtype, DataType.Type):
3912            data_type_exp = DataType(this=dtype)
3913        elif isinstance(dtype, DataType):
3914            return maybe_copy(dtype, copy)
3915        else:
3916            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3917
3918        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:
3920    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3921        """
3922        Checks whether this DataType matches one of the provided data types. Nested types or precision
3923        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3924
3925        Args:
3926            dtypes: the data types to compare this DataType to.
3927
3928        Returns:
3929            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3930        """
3931        for dtype in dtypes:
3932            other = DataType.build(dtype, copy=False, udt=True)
3933
3934            if (
3935                other.expressions
3936                or self.this == DataType.Type.USERDEFINED
3937                or other.this == DataType.Type.USERDEFINED
3938            ):
3939                matches = self == other
3940            else:
3941                matches = self.this == other.this
3942
3943            if matches:
3944                return True
3945        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):
3711    class Type(AutoName):
3712        ARRAY = auto()
3713        AGGREGATEFUNCTION = auto()
3714        SIMPLEAGGREGATEFUNCTION = auto()
3715        BIGDECIMAL = auto()
3716        BIGINT = auto()
3717        BIGSERIAL = auto()
3718        BINARY = auto()
3719        BIT = auto()
3720        BOOLEAN = auto()
3721        BPCHAR = auto()
3722        CHAR = auto()
3723        DATE = auto()
3724        DATE32 = auto()
3725        DATEMULTIRANGE = auto()
3726        DATERANGE = auto()
3727        DATETIME = auto()
3728        DATETIME64 = auto()
3729        DECIMAL = auto()
3730        DOUBLE = auto()
3731        ENUM = auto()
3732        ENUM8 = auto()
3733        ENUM16 = auto()
3734        FIXEDSTRING = auto()
3735        FLOAT = auto()
3736        GEOGRAPHY = auto()
3737        GEOMETRY = auto()
3738        HLLSKETCH = auto()
3739        HSTORE = auto()
3740        IMAGE = auto()
3741        INET = auto()
3742        INT = auto()
3743        INT128 = auto()
3744        INT256 = auto()
3745        INT4MULTIRANGE = auto()
3746        INT4RANGE = auto()
3747        INT8MULTIRANGE = auto()
3748        INT8RANGE = auto()
3749        INTERVAL = auto()
3750        IPADDRESS = auto()
3751        IPPREFIX = auto()
3752        IPV4 = auto()
3753        IPV6 = auto()
3754        JSON = auto()
3755        JSONB = auto()
3756        LONGBLOB = auto()
3757        LONGTEXT = auto()
3758        LOWCARDINALITY = auto()
3759        MAP = auto()
3760        MEDIUMBLOB = auto()
3761        MEDIUMINT = auto()
3762        MEDIUMTEXT = auto()
3763        MONEY = auto()
3764        NCHAR = auto()
3765        NESTED = auto()
3766        NULL = auto()
3767        NULLABLE = auto()
3768        NUMMULTIRANGE = auto()
3769        NUMRANGE = auto()
3770        NVARCHAR = auto()
3771        OBJECT = auto()
3772        ROWVERSION = auto()
3773        SERIAL = auto()
3774        SET = auto()
3775        SMALLINT = auto()
3776        SMALLMONEY = auto()
3777        SMALLSERIAL = auto()
3778        STRUCT = auto()
3779        SUPER = auto()
3780        TEXT = auto()
3781        TINYBLOB = auto()
3782        TINYTEXT = auto()
3783        TIME = auto()
3784        TIMETZ = auto()
3785        TIMESTAMP = auto()
3786        TIMESTAMPLTZ = auto()
3787        TIMESTAMPTZ = auto()
3788        TIMESTAMP_S = auto()
3789        TIMESTAMP_MS = auto()
3790        TIMESTAMP_NS = auto()
3791        TINYINT = auto()
3792        TSMULTIRANGE = auto()
3793        TSRANGE = auto()
3794        TSTZMULTIRANGE = auto()
3795        TSTZRANGE = auto()
3796        UBIGINT = auto()
3797        UINT = auto()
3798        UINT128 = auto()
3799        UINT256 = auto()
3800        UMEDIUMINT = auto()
3801        UDECIMAL = auto()
3802        UNIQUEIDENTIFIER = auto()
3803        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3804        USERDEFINED = "USER-DEFINED"
3805        USMALLINT = auto()
3806        UTINYINT = auto()
3807        UUID = auto()
3808        VARBINARY = auto()
3809        VARCHAR = auto()
3810        VARIANT = auto()
3811        XML = auto()
3812        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):
3952class PseudoType(DataType):
3953    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3957class ObjectIdentifier(DataType):
3958    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3962class SubqueryPredicate(Predicate):
3963    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3966class All(SubqueryPredicate):
3967    pass
key = 'all'
class Any(SubqueryPredicate):
3970class Any(SubqueryPredicate):
3971    pass
key = 'any'
class Exists(SubqueryPredicate):
3974class Exists(SubqueryPredicate):
3975    pass
key = 'exists'
class Command(Expression):
3980class Command(Expression):
3981    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3984class Transaction(Expression):
3985    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3988class Commit(Expression):
3989    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3992class Rollback(Expression):
3993    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3996class AlterTable(Expression):
3997    arg_types = {
3998        "this": True,
3999        "actions": True,
4000        "exists": False,
4001        "only": False,
4002        "options": False,
4003    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4006class AddConstraint(Expression):
4007    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4010class DropPartition(Expression):
4011    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4015class Binary(Condition):
4016    arg_types = {"this": True, "expression": True}
4017
4018    @property
4019    def left(self) -> Expression:
4020        return self.this
4021
4022    @property
4023    def right(self) -> Expression:
4024        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4018    @property
4019    def left(self) -> Expression:
4020        return self.this
right: Expression
4022    @property
4023    def right(self) -> Expression:
4024        return self.expression
key = 'binary'
class Add(Binary):
4027class Add(Binary):
4028    pass
key = 'add'
class Connector(Binary):
4031class Connector(Binary):
4032    pass
key = 'connector'
class And(Connector):
4035class And(Connector):
4036    pass
key = 'and'
class Or(Connector):
4039class Or(Connector):
4040    pass
key = 'or'
class BitwiseAnd(Binary):
4043class BitwiseAnd(Binary):
4044    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4047class BitwiseLeftShift(Binary):
4048    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4051class BitwiseOr(Binary):
4052    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4055class BitwiseRightShift(Binary):
4056    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4059class BitwiseXor(Binary):
4060    pass
key = 'bitwisexor'
class Div(Binary):
4063class Div(Binary):
4064    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):
4067class Overlaps(Binary):
4068    pass
key = 'overlaps'
class Dot(Binary):
4071class Dot(Binary):
4072    @property
4073    def is_star(self) -> bool:
4074        return self.expression.is_star
4075
4076    @property
4077    def name(self) -> str:
4078        return self.expression.name
4079
4080    @property
4081    def output_name(self) -> str:
4082        return self.name
4083
4084    @classmethod
4085    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4086        """Build a Dot object with a sequence of expressions."""
4087        if len(expressions) < 2:
4088            raise ValueError("Dot requires >= 2 expressions.")
4089
4090        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4091
4092    @property
4093    def parts(self) -> t.List[Expression]:
4094        """Return the parts of a table / column in order catalog, db, table."""
4095        this, *parts = self.flatten()
4096
4097        parts.reverse()
4098
4099        for arg in ("this", "table", "db", "catalog"):
4100            part = this.args.get(arg)
4101
4102            if isinstance(part, Expression):
4103                parts.append(part)
4104
4105        parts.reverse()
4106        return parts
is_star: bool
4072    @property
4073    def is_star(self) -> bool:
4074        return self.expression.is_star

Checks whether an expression is a star.

name: str
4076    @property
4077    def name(self) -> str:
4078        return self.expression.name
output_name: str
4080    @property
4081    def output_name(self) -> str:
4082        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:
4084    @classmethod
4085    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4086        """Build a Dot object with a sequence of expressions."""
4087        if len(expressions) < 2:
4088            raise ValueError("Dot requires >= 2 expressions.")
4089
4090        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]
4092    @property
4093    def parts(self) -> t.List[Expression]:
4094        """Return the parts of a table / column in order catalog, db, table."""
4095        this, *parts = self.flatten()
4096
4097        parts.reverse()
4098
4099        for arg in ("this", "table", "db", "catalog"):
4100            part = this.args.get(arg)
4101
4102            if isinstance(part, Expression):
4103                parts.append(part)
4104
4105        parts.reverse()
4106        return parts

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

key = 'dot'
class DPipe(Binary):
4109class DPipe(Binary):
4110    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4113class EQ(Binary, Predicate):
4114    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4117class NullSafeEQ(Binary, Predicate):
4118    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4121class NullSafeNEQ(Binary, Predicate):
4122    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4126class PropertyEQ(Binary):
4127    pass
key = 'propertyeq'
class Distance(Binary):
4130class Distance(Binary):
4131    pass
key = 'distance'
class Escape(Binary):
4134class Escape(Binary):
4135    pass
key = 'escape'
class Glob(Binary, Predicate):
4138class Glob(Binary, Predicate):
4139    pass
key = 'glob'
class GT(Binary, Predicate):
4142class GT(Binary, Predicate):
4143    pass
key = 'gt'
class GTE(Binary, Predicate):
4146class GTE(Binary, Predicate):
4147    pass
key = 'gte'
class ILike(Binary, Predicate):
4150class ILike(Binary, Predicate):
4151    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4154class ILikeAny(Binary, Predicate):
4155    pass
key = 'ilikeany'
class IntDiv(Binary):
4158class IntDiv(Binary):
4159    pass
key = 'intdiv'
class Is(Binary, Predicate):
4162class Is(Binary, Predicate):
4163    pass
key = 'is'
class Kwarg(Binary):
4166class Kwarg(Binary):
4167    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4170class Like(Binary, Predicate):
4171    pass
key = 'like'
class LikeAny(Binary, Predicate):
4174class LikeAny(Binary, Predicate):
4175    pass
key = 'likeany'
class LT(Binary, Predicate):
4178class LT(Binary, Predicate):
4179    pass
key = 'lt'
class LTE(Binary, Predicate):
4182class LTE(Binary, Predicate):
4183    pass
key = 'lte'
class Mod(Binary):
4186class Mod(Binary):
4187    pass
key = 'mod'
class Mul(Binary):
4190class Mul(Binary):
4191    pass
key = 'mul'
class NEQ(Binary, Predicate):
4194class NEQ(Binary, Predicate):
4195    pass
key = 'neq'
class Operator(Binary):
4199class Operator(Binary):
4200    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4203class SimilarTo(Binary, Predicate):
4204    pass
key = 'similarto'
class Slice(Binary):
4207class Slice(Binary):
4208    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4211class Sub(Binary):
4212    pass
key = 'sub'
class Unary(Condition):
4217class Unary(Condition):
4218    pass
key = 'unary'
class BitwiseNot(Unary):
4221class BitwiseNot(Unary):
4222    pass
key = 'bitwisenot'
class Not(Unary):
4225class Not(Unary):
4226    pass
key = 'not'
class Paren(Unary):
4229class Paren(Unary):
4230    arg_types = {"this": True, "with": False}
4231
4232    @property
4233    def output_name(self) -> str:
4234        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4232    @property
4233    def output_name(self) -> str:
4234        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):
4237class Neg(Unary):
4238    pass
key = 'neg'
class Alias(Expression):
4241class Alias(Expression):
4242    arg_types = {"this": True, "alias": False}
4243
4244    @property
4245    def output_name(self) -> str:
4246        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4244    @property
4245    def output_name(self) -> str:
4246        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):
4251class PivotAlias(Alias):
4252    pass
key = 'pivotalias'
class Aliases(Expression):
4255class Aliases(Expression):
4256    arg_types = {"this": True, "expressions": True}
4257
4258    @property
4259    def aliases(self):
4260        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4258    @property
4259    def aliases(self):
4260        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4264class AtIndex(Expression):
4265    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4268class AtTimeZone(Expression):
4269    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4272class FromTimeZone(Expression):
4273    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4276class Between(Predicate):
4277    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4280class Bracket(Condition):
4281    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4282    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4283
4284    @property
4285    def output_name(self) -> str:
4286        if len(self.expressions) == 1:
4287            return self.expressions[0].output_name
4288
4289        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4284    @property
4285    def output_name(self) -> str:
4286        if len(self.expressions) == 1:
4287            return self.expressions[0].output_name
4288
4289        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):
4292class Distinct(Expression):
4293    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4296class In(Predicate):
4297    arg_types = {
4298        "this": True,
4299        "expressions": False,
4300        "query": False,
4301        "unnest": False,
4302        "field": False,
4303        "is_global": False,
4304    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4308class ForIn(Expression):
4309    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4312class TimeUnit(Expression):
4313    """Automatically converts unit arg into a var."""
4314
4315    arg_types = {"unit": False}
4316
4317    UNABBREVIATED_UNIT_NAME = {
4318        "D": "DAY",
4319        "H": "HOUR",
4320        "M": "MINUTE",
4321        "MS": "MILLISECOND",
4322        "NS": "NANOSECOND",
4323        "Q": "QUARTER",
4324        "S": "SECOND",
4325        "US": "MICROSECOND",
4326        "W": "WEEK",
4327        "Y": "YEAR",
4328    }
4329
4330    VAR_LIKE = (Column, Literal, Var)
4331
4332    def __init__(self, **args):
4333        unit = args.get("unit")
4334        if isinstance(unit, self.VAR_LIKE):
4335            args["unit"] = Var(
4336                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4337            )
4338        elif isinstance(unit, Week):
4339            unit.set("this", Var(this=unit.this.name.upper()))
4340
4341        super().__init__(**args)
4342
4343    @property
4344    def unit(self) -> t.Optional[Var]:
4345        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4332    def __init__(self, **args):
4333        unit = args.get("unit")
4334        if isinstance(unit, self.VAR_LIKE):
4335            args["unit"] = Var(
4336                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4337            )
4338        elif isinstance(unit, Week):
4339            unit.set("this", Var(this=unit.this.name.upper()))
4340
4341        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]
4343    @property
4344    def unit(self) -> t.Optional[Var]:
4345        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4348class IntervalOp(TimeUnit):
4349    arg_types = {"unit": True, "expression": True}
4350
4351    def interval(self):
4352        return Interval(
4353            this=self.expression.copy(),
4354            unit=self.unit.copy(),
4355        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4351    def interval(self):
4352        return Interval(
4353            this=self.expression.copy(),
4354            unit=self.unit.copy(),
4355        )
key = 'intervalop'
class IntervalSpan(DataType):
4361class IntervalSpan(DataType):
4362    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4365class Interval(TimeUnit):
4366    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4369class IgnoreNulls(Expression):
4370    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4373class RespectNulls(Expression):
4374    pass
key = 'respectnulls'
class HavingMax(Expression):
4378class HavingMax(Expression):
4379    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4383class Func(Condition):
4384    """
4385    The base class for all function expressions.
4386
4387    Attributes:
4388        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4389            treated as a variable length argument and the argument's value will be stored as a list.
4390        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4391            function expression. These values are used to map this node to a name during parsing as
4392            well as to provide the function's name during SQL string generation. By default the SQL
4393            name is set to the expression's class name transformed to snake case.
4394    """
4395
4396    is_var_len_args = False
4397
4398    @classmethod
4399    def from_arg_list(cls, args):
4400        if cls.is_var_len_args:
4401            all_arg_keys = list(cls.arg_types)
4402            # If this function supports variable length argument treat the last argument as such.
4403            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4404            num_non_var = len(non_var_len_arg_keys)
4405
4406            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4407            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4408        else:
4409            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4410
4411        return cls(**args_dict)
4412
4413    @classmethod
4414    def sql_names(cls):
4415        if cls is Func:
4416            raise NotImplementedError(
4417                "SQL name is only supported by concrete function implementations"
4418            )
4419        if "_sql_names" not in cls.__dict__:
4420            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4421        return cls._sql_names
4422
4423    @classmethod
4424    def sql_name(cls):
4425        return cls.sql_names()[0]
4426
4427    @classmethod
4428    def default_parser_mappings(cls):
4429        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):
4398    @classmethod
4399    def from_arg_list(cls, args):
4400        if cls.is_var_len_args:
4401            all_arg_keys = list(cls.arg_types)
4402            # If this function supports variable length argument treat the last argument as such.
4403            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4404            num_non_var = len(non_var_len_arg_keys)
4405
4406            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4407            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4408        else:
4409            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4410
4411        return cls(**args_dict)
@classmethod
def sql_names(cls):
4413    @classmethod
4414    def sql_names(cls):
4415        if cls is Func:
4416            raise NotImplementedError(
4417                "SQL name is only supported by concrete function implementations"
4418            )
4419        if "_sql_names" not in cls.__dict__:
4420            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4421        return cls._sql_names
@classmethod
def sql_name(cls):
4423    @classmethod
4424    def sql_name(cls):
4425        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4427    @classmethod
4428    def default_parser_mappings(cls):
4429        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4432class AggFunc(Func):
4433    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4436class ParameterizedAgg(AggFunc):
4437    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4440class Abs(Func):
4441    pass
key = 'abs'
class ArgMax(AggFunc):
4444class ArgMax(AggFunc):
4445    arg_types = {"this": True, "expression": True, "count": False}
4446    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4449class ArgMin(AggFunc):
4450    arg_types = {"this": True, "expression": True, "count": False}
4451    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4454class ApproxTopK(AggFunc):
4455    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4458class Flatten(Func):
4459    pass
key = 'flatten'
class Transform(Func):
4463class Transform(Func):
4464    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4467class Anonymous(Func):
4468    arg_types = {"this": True, "expressions": False}
4469    is_var_len_args = True
4470
4471    @property
4472    def name(self) -> str:
4473        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
4471    @property
4472    def name(self) -> str:
4473        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4476class AnonymousAggFunc(AggFunc):
4477    arg_types = {"this": True, "expressions": False}
4478    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4482class CombinedAggFunc(AnonymousAggFunc):
4483    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4486class CombinedParameterizedAgg(ParameterizedAgg):
4487    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):
4492class Hll(AggFunc):
4493    arg_types = {"this": True, "expressions": False}
4494    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4497class ApproxDistinct(AggFunc):
4498    arg_types = {"this": True, "accuracy": False}
4499    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4502class Array(Func):
4503    arg_types = {"expressions": False}
4504    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4508class ToArray(Func):
4509    pass
key = 'toarray'
class ToChar(Func):
4514class ToChar(Func):
4515    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class Convert(Func):
4519class Convert(Func):
4520    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4523class GenerateSeries(Func):
4524    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):
4527class ArrayAgg(AggFunc):
4528    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4531class ArrayUniqueAgg(AggFunc):
4532    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4535class ArrayAll(Func):
4536    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4540class ArrayAny(Func):
4541    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4544class ArrayConcat(Func):
4545    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4546    arg_types = {"this": True, "expressions": False}
4547    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4550class ArrayContains(Binary, Func):
4551    pass
key = 'arraycontains'
class ArrayContained(Binary):
4554class ArrayContained(Binary):
4555    pass
key = 'arraycontained'
class ArrayFilter(Func):
4558class ArrayFilter(Func):
4559    arg_types = {"this": True, "expression": True}
4560    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4563class ArrayJoin(Func):
4564    arg_types = {"this": True, "expression": True, "null": False}
4565    _sql_names = ["ARRAY_JOIN", "ARRAY_TO_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4568class ArrayOverlaps(Binary, Func):
4569    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4572class ArraySize(Func):
4573    arg_types = {"this": True, "expression": False}
4574    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4577class ArraySort(Func):
4578    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4581class ArraySum(Func):
4582    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4585class ArrayUnionAgg(AggFunc):
4586    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4589class Avg(AggFunc):
4590    pass
key = 'avg'
class AnyValue(AggFunc):
4593class AnyValue(AggFunc):
4594    pass
key = 'anyvalue'
class Lag(AggFunc):
4597class Lag(AggFunc):
4598    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4601class Lead(AggFunc):
4602    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4607class First(AggFunc):
4608    pass
key = 'first'
class Last(AggFunc):
4611class Last(AggFunc):
4612    pass
key = 'last'
class FirstValue(AggFunc):
4615class FirstValue(AggFunc):
4616    pass
key = 'firstvalue'
class LastValue(AggFunc):
4619class LastValue(AggFunc):
4620    pass
key = 'lastvalue'
class NthValue(AggFunc):
4623class NthValue(AggFunc):
4624    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4627class Case(Func):
4628    arg_types = {"this": False, "ifs": True, "default": False}
4629
4630    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4631        instance = maybe_copy(self, copy)
4632        instance.append(
4633            "ifs",
4634            If(
4635                this=maybe_parse(condition, copy=copy, **opts),
4636                true=maybe_parse(then, copy=copy, **opts),
4637            ),
4638        )
4639        return instance
4640
4641    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4642        instance = maybe_copy(self, copy)
4643        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4644        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:
4630    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4631        instance = maybe_copy(self, copy)
4632        instance.append(
4633            "ifs",
4634            If(
4635                this=maybe_parse(condition, copy=copy, **opts),
4636                true=maybe_parse(then, copy=copy, **opts),
4637            ),
4638        )
4639        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4641    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4642        instance = maybe_copy(self, copy)
4643        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4644        return instance
key = 'case'
class Cast(Func):
4647class Cast(Func):
4648    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4649
4650    @property
4651    def name(self) -> str:
4652        return self.this.name
4653
4654    @property
4655    def to(self) -> DataType:
4656        return self.args["to"]
4657
4658    @property
4659    def output_name(self) -> str:
4660        return self.name
4661
4662    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4663        """
4664        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4665        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4666        array<int> != array<float>.
4667
4668        Args:
4669            dtypes: the data types to compare this Cast's DataType to.
4670
4671        Returns:
4672            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4673        """
4674        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4650    @property
4651    def name(self) -> str:
4652        return self.this.name
to: DataType
4654    @property
4655    def to(self) -> DataType:
4656        return self.args["to"]
output_name: str
4658    @property
4659    def output_name(self) -> str:
4660        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:
4662    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4663        """
4664        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4665        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4666        array<int> != array<float>.
4667
4668        Args:
4669            dtypes: the data types to compare this Cast's DataType to.
4670
4671        Returns:
4672            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4673        """
4674        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):
4677class TryCast(Cast):
4678    pass
key = 'trycast'
class CastToStrType(Func):
4681class CastToStrType(Func):
4682    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4685class Collate(Binary, Func):
4686    pass
key = 'collate'
class Ceil(Func):
4689class Ceil(Func):
4690    arg_types = {"this": True, "decimals": False}
4691    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4694class Coalesce(Func):
4695    arg_types = {"this": True, "expressions": False}
4696    is_var_len_args = True
4697    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4700class Chr(Func):
4701    arg_types = {"this": True, "charset": False, "expressions": False}
4702    is_var_len_args = True
4703    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4706class Concat(Func):
4707    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4708    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4711class ConcatWs(Concat):
4712    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4716class ConnectByRoot(Func):
4717    pass
key = 'connectbyroot'
class Count(AggFunc):
4720class Count(AggFunc):
4721    arg_types = {"this": False, "expressions": False}
4722    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4725class CountIf(AggFunc):
4726    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4730class Cbrt(Func):
4731    pass
key = 'cbrt'
class CurrentDate(Func):
4734class CurrentDate(Func):
4735    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4738class CurrentDatetime(Func):
4739    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4742class CurrentTime(Func):
4743    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4746class CurrentTimestamp(Func):
4747    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4750class CurrentUser(Func):
4751    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4754class DateAdd(Func, IntervalOp):
4755    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4758class DateSub(Func, IntervalOp):
4759    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4762class DateDiff(Func, TimeUnit):
4763    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4764    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4767class DateTrunc(Func):
4768    arg_types = {"unit": True, "this": True, "zone": False}
4769
4770    def __init__(self, **args):
4771        unit = args.get("unit")
4772        if isinstance(unit, TimeUnit.VAR_LIKE):
4773            args["unit"] = Literal.string(
4774                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4775            )
4776        elif isinstance(unit, Week):
4777            unit.set("this", Literal.string(unit.this.name.upper()))
4778
4779        super().__init__(**args)
4780
4781    @property
4782    def unit(self) -> Expression:
4783        return self.args["unit"]
DateTrunc(**args)
4770    def __init__(self, **args):
4771        unit = args.get("unit")
4772        if isinstance(unit, TimeUnit.VAR_LIKE):
4773            args["unit"] = Literal.string(
4774                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4775            )
4776        elif isinstance(unit, Week):
4777            unit.set("this", Literal.string(unit.this.name.upper()))
4778
4779        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4781    @property
4782    def unit(self) -> Expression:
4783        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4786class DatetimeAdd(Func, IntervalOp):
4787    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4790class DatetimeSub(Func, IntervalOp):
4791    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4794class DatetimeDiff(Func, TimeUnit):
4795    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4798class DatetimeTrunc(Func, TimeUnit):
4799    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4802class DayOfWeek(Func):
4803    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4806class DayOfMonth(Func):
4807    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4810class DayOfYear(Func):
4811    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4814class ToDays(Func):
4815    pass
key = 'todays'
class WeekOfYear(Func):
4818class WeekOfYear(Func):
4819    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4822class MonthsBetween(Func):
4823    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4826class LastDay(Func, TimeUnit):
4827    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4828    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4831class Extract(Func):
4832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4835class Timestamp(Func):
4836    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4839class TimestampAdd(Func, TimeUnit):
4840    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4843class TimestampSub(Func, TimeUnit):
4844    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4847class TimestampDiff(Func, TimeUnit):
4848    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4849    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4852class TimestampTrunc(Func, TimeUnit):
4853    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4856class TimeAdd(Func, TimeUnit):
4857    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4860class TimeSub(Func, TimeUnit):
4861    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4864class TimeDiff(Func, TimeUnit):
4865    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4868class TimeTrunc(Func, TimeUnit):
4869    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4872class DateFromParts(Func):
4873    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4874    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4877class TimeFromParts(Func):
4878    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4879    arg_types = {
4880        "hour": True,
4881        "min": True,
4882        "sec": True,
4883        "nano": False,
4884        "fractions": False,
4885        "precision": False,
4886    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4889class DateStrToDate(Func):
4890    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4893class DateToDateStr(Func):
4894    pass
key = 'datetodatestr'
class DateToDi(Func):
4897class DateToDi(Func):
4898    pass
key = 'datetodi'
class Date(Func):
4902class Date(Func):
4903    arg_types = {"this": False, "zone": False, "expressions": False}
4904    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4907class Day(Func):
4908    pass
key = 'day'
class Decode(Func):
4911class Decode(Func):
4912    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4915class DiToDate(Func):
4916    pass
key = 'ditodate'
class Encode(Func):
4919class Encode(Func):
4920    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4923class Exp(Func):
4924    pass
key = 'exp'
class Explode(Func):
4928class Explode(Func):
4929    arg_types = {"this": True, "expressions": False}
4930    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4933class ExplodeOuter(Explode):
4934    pass
key = 'explodeouter'
class Posexplode(Explode):
4937class Posexplode(Explode):
4938    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4941class PosexplodeOuter(Posexplode, ExplodeOuter):
4942    pass
key = 'posexplodeouter'
class Floor(Func):
4945class Floor(Func):
4946    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4949class FromBase64(Func):
4950    pass
key = 'frombase64'
class ToBase64(Func):
4953class ToBase64(Func):
4954    pass
key = 'tobase64'
class Greatest(Func):
4957class Greatest(Func):
4958    arg_types = {"this": True, "expressions": False}
4959    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4962class GroupConcat(AggFunc):
4963    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4966class Hex(Func):
4967    pass
key = 'hex'
class Xor(Connector, Func):
4970class Xor(Connector, Func):
4971    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4974class If(Func):
4975    arg_types = {"this": True, "true": True, "false": False}
4976    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4979class Nullif(Func):
4980    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4983class Initcap(Func):
4984    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4987class IsNan(Func):
4988    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4991class IsInf(Func):
4992    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4995class JSONPath(Expression):
4996    arg_types = {"expressions": True}
4997
4998    @property
4999    def output_name(self) -> str:
5000        last_segment = self.expressions[-1].this
5001        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4998    @property
4999    def output_name(self) -> str:
5000        last_segment = self.expressions[-1].this
5001        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):
5004class JSONPathPart(Expression):
5005    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5008class JSONPathFilter(JSONPathPart):
5009    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5012class JSONPathKey(JSONPathPart):
5013    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5016class JSONPathRecursive(JSONPathPart):
5017    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5020class JSONPathRoot(JSONPathPart):
5021    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5024class JSONPathScript(JSONPathPart):
5025    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5028class JSONPathSlice(JSONPathPart):
5029    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5032class JSONPathSelector(JSONPathPart):
5033    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5036class JSONPathSubscript(JSONPathPart):
5037    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5040class JSONPathUnion(JSONPathPart):
5041    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5044class JSONPathWildcard(JSONPathPart):
5045    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5048class FormatJson(Expression):
5049    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5052class JSONKeyValue(Expression):
5053    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5056class JSONObject(Func):
5057    arg_types = {
5058        "expressions": False,
5059        "null_handling": False,
5060        "unique_keys": False,
5061        "return_type": False,
5062        "encoding": False,
5063    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5066class JSONObjectAgg(AggFunc):
5067    arg_types = {
5068        "expressions": False,
5069        "null_handling": False,
5070        "unique_keys": False,
5071        "return_type": False,
5072        "encoding": False,
5073    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5077class JSONArray(Func):
5078    arg_types = {
5079        "expressions": True,
5080        "null_handling": False,
5081        "return_type": False,
5082        "strict": False,
5083    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5087class JSONArrayAgg(Func):
5088    arg_types = {
5089        "this": True,
5090        "order": False,
5091        "null_handling": False,
5092        "return_type": False,
5093        "strict": False,
5094    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5099class JSONColumnDef(Expression):
5100    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):
5103class JSONSchema(Expression):
5104    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5108class JSONTable(Func):
5109    arg_types = {
5110        "this": True,
5111        "schema": True,
5112        "path": False,
5113        "error_handling": False,
5114        "empty_handling": False,
5115    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5118class OpenJSONColumnDef(Expression):
5119    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):
5122class OpenJSON(Func):
5123    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5126class JSONBContains(Binary):
5127    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5130class JSONExtract(Binary, Func):
5131    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5132    _sql_names = ["JSON_EXTRACT"]
5133    is_var_len_args = True
5134
5135    @property
5136    def output_name(self) -> str:
5137        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
5135    @property
5136    def output_name(self) -> str:
5137        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):
5140class JSONExtractScalar(Binary, Func):
5141    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5142    _sql_names = ["JSON_EXTRACT_SCALAR"]
5143    is_var_len_args = True
5144
5145    @property
5146    def output_name(self) -> str:
5147        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
5145    @property
5146    def output_name(self) -> str:
5147        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):
5150class JSONBExtract(Binary, Func):
5151    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5154class JSONBExtractScalar(Binary, Func):
5155    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5158class JSONFormat(Func):
5159    arg_types = {"this": False, "options": False}
5160    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5164class JSONArrayContains(Binary, Predicate, Func):
5165    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5168class ParseJSON(Func):
5169    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5170    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5171    arg_types = {"this": True, "expressions": False}
5172    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5175class Least(Func):
5176    arg_types = {"this": True, "expressions": False}
5177    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5180class Left(Func):
5181    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5188class Length(Func):
5189    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5192class Levenshtein(Func):
5193    arg_types = {
5194        "this": True,
5195        "expression": False,
5196        "ins_cost": False,
5197        "del_cost": False,
5198        "sub_cost": False,
5199    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5202class Ln(Func):
5203    pass
key = 'ln'
class Log(Func):
5206class Log(Func):
5207    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5210class Log2(Func):
5211    pass
key = 'log2'
class Log10(Func):
5214class Log10(Func):
5215    pass
key = 'log10'
class LogicalOr(AggFunc):
5218class LogicalOr(AggFunc):
5219    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5222class LogicalAnd(AggFunc):
5223    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5226class Lower(Func):
5227    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5230class Map(Func):
5231    arg_types = {"keys": False, "values": False}
5232
5233    @property
5234    def keys(self) -> t.List[Expression]:
5235        keys = self.args.get("keys")
5236        return keys.expressions if keys else []
5237
5238    @property
5239    def values(self) -> t.List[Expression]:
5240        values = self.args.get("values")
5241        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5233    @property
5234    def keys(self) -> t.List[Expression]:
5235        keys = self.args.get("keys")
5236        return keys.expressions if keys else []
values: List[Expression]
5238    @property
5239    def values(self) -> t.List[Expression]:
5240        values = self.args.get("values")
5241        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5244class MapFromEntries(Func):
5245    pass
key = 'mapfromentries'
class StarMap(Func):
5248class StarMap(Func):
5249    pass
key = 'starmap'
class VarMap(Func):
5252class VarMap(Func):
5253    arg_types = {"keys": True, "values": True}
5254    is_var_len_args = True
5255
5256    @property
5257    def keys(self) -> t.List[Expression]:
5258        return self.args["keys"].expressions
5259
5260    @property
5261    def values(self) -> t.List[Expression]:
5262        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5256    @property
5257    def keys(self) -> t.List[Expression]:
5258        return self.args["keys"].expressions
values: List[Expression]
5260    @property
5261    def values(self) -> t.List[Expression]:
5262        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5266class MatchAgainst(Func):
5267    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5270class Max(AggFunc):
5271    arg_types = {"this": True, "expressions": False}
5272    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5275class MD5(Func):
5276    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5280class MD5Digest(Func):
5281    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5284class Min(AggFunc):
5285    arg_types = {"this": True, "expressions": False}
5286    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5289class Month(Func):
5290    pass
key = 'month'
class AddMonths(Func):
5293class AddMonths(Func):
5294    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5297class Nvl2(Func):
5298    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5302class Predict(Func):
5303    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5306class Pow(Binary, Func):
5307    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5310class PercentileCont(AggFunc):
5311    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5314class PercentileDisc(AggFunc):
5315    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5318class Quantile(AggFunc):
5319    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5322class ApproxQuantile(Quantile):
5323    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):
5326class Rand(Func):
5327    _sql_names = ["RAND", "RANDOM"]
5328    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5331class Randn(Func):
5332    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5335class RangeN(Func):
5336    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5339class ReadCSV(Func):
5340    _sql_names = ["READ_CSV"]
5341    is_var_len_args = True
5342    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5345class Reduce(Func):
5346    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):
5349class RegexpExtract(Func):
5350    arg_types = {
5351        "this": True,
5352        "expression": True,
5353        "position": False,
5354        "occurrence": False,
5355        "parameters": False,
5356        "group": False,
5357    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5360class RegexpReplace(Func):
5361    arg_types = {
5362        "this": True,
5363        "expression": True,
5364        "replacement": False,
5365        "position": False,
5366        "occurrence": False,
5367        "parameters": False,
5368        "modifiers": False,
5369    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5372class RegexpLike(Binary, Func):
5373    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5376class RegexpILike(Binary, Func):
5377    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5382class RegexpSplit(Func):
5383    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5386class Repeat(Func):
5387    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5392class Round(Func):
5393    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5396class RowNumber(Func):
5397    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5400class SafeDivide(Func):
5401    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5404class SHA(Func):
5405    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5408class SHA2(Func):
5409    _sql_names = ["SHA2"]
5410    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5413class Sign(Func):
5414    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5417class SortArray(Func):
5418    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5421class Split(Func):
5422    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5427class Substring(Func):
5428    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5431class StandardHash(Func):
5432    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5435class StartsWith(Func):
5436    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5437    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5440class StrPosition(Func):
5441    arg_types = {
5442        "this": True,
5443        "substr": True,
5444        "position": False,
5445        "instance": False,
5446    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5449class StrToDate(Func):
5450    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5453class StrToTime(Func):
5454    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5459class StrToUnix(Func):
5460    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5465class StrToMap(Func):
5466    arg_types = {
5467        "this": True,
5468        "pair_delim": False,
5469        "key_value_delim": False,
5470        "duplicate_resolution_callback": False,
5471    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5474class NumberToStr(Func):
5475    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5478class FromBase(Func):
5479    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5482class Struct(Func):
5483    arg_types = {"expressions": False}
5484    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5487class StructExtract(Func):
5488    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5493class Stuff(Func):
5494    _sql_names = ["STUFF", "INSERT"]
5495    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):
5498class Sum(AggFunc):
5499    pass
key = 'sum'
class Sqrt(Func):
5502class Sqrt(Func):
5503    pass
key = 'sqrt'
class Stddev(AggFunc):
5506class Stddev(AggFunc):
5507    pass
key = 'stddev'
class StddevPop(AggFunc):
5510class StddevPop(AggFunc):
5511    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5514class StddevSamp(AggFunc):
5515    pass
key = 'stddevsamp'
class TimeToStr(Func):
5518class TimeToStr(Func):
5519    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5522class TimeToTimeStr(Func):
5523    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5526class TimeToUnix(Func):
5527    pass
key = 'timetounix'
class TimeStrToDate(Func):
5530class TimeStrToDate(Func):
5531    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5534class TimeStrToTime(Func):
5535    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5538class TimeStrToUnix(Func):
5539    pass
key = 'timestrtounix'
class Trim(Func):
5542class Trim(Func):
5543    arg_types = {
5544        "this": True,
5545        "expression": False,
5546        "position": False,
5547        "collation": False,
5548    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5551class TsOrDsAdd(Func, TimeUnit):
5552    # return_type is used to correctly cast the arguments of this expression when transpiling it
5553    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5554
5555    @property
5556    def return_type(self) -> DataType:
5557        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
5555    @property
5556    def return_type(self) -> DataType:
5557        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5560class TsOrDsDiff(Func, TimeUnit):
5561    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5564class TsOrDsToDateStr(Func):
5565    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5568class TsOrDsToDate(Func):
5569    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5572class TsOrDsToTime(Func):
5573    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5576class TsOrDiToDi(Func):
5577    pass
key = 'tsorditodi'
class Unhex(Func):
5580class Unhex(Func):
5581    pass
key = 'unhex'
class UnixDate(Func):
5585class UnixDate(Func):
5586    pass
key = 'unixdate'
class UnixToStr(Func):
5589class UnixToStr(Func):
5590    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5595class UnixToTime(Func):
5596    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5597
5598    SECONDS = Literal.number(0)
5599    DECIS = Literal.number(1)
5600    CENTIS = Literal.number(2)
5601    MILLIS = Literal.number(3)
5602    DECIMILLIS = Literal.number(4)
5603    CENTIMILLIS = Literal.number(5)
5604    MICROS = Literal.number(6)
5605    DECIMICROS = Literal.number(7)
5606    CENTIMICROS = Literal.number(8)
5607    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):
5610class UnixToTimeStr(Func):
5611    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5614class TimestampFromParts(Func):
5615    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5616    arg_types = {
5617        "year": True,
5618        "month": True,
5619        "day": True,
5620        "hour": True,
5621        "min": True,
5622        "sec": True,
5623        "nano": False,
5624        "zone": False,
5625        "milli": False,
5626    }
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):
5629class Upper(Func):
5630    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5633class Variance(AggFunc):
5634    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5637class VariancePop(AggFunc):
5638    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5641class Week(Func):
5642    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5645class XMLTable(Func):
5646    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):
5649class Year(Func):
5650    pass
key = 'year'
class Use(Expression):
5653class Use(Expression):
5654    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5657class Merge(Expression):
5658    arg_types = {
5659        "this": True,
5660        "using": True,
5661        "on": True,
5662        "expressions": True,
5663        "with": False,
5664    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5667class When(Func):
5668    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):
5673class NextValueFor(Func):
5674    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_TO_STRING': <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:
5712def maybe_parse(
5713    sql_or_expression: ExpOrStr,
5714    *,
5715    into: t.Optional[IntoType] = None,
5716    dialect: DialectType = None,
5717    prefix: t.Optional[str] = None,
5718    copy: bool = False,
5719    **opts,
5720) -> Expression:
5721    """Gracefully handle a possible string or expression.
5722
5723    Example:
5724        >>> maybe_parse("1")
5725        Literal(this=1, is_string=False)
5726        >>> maybe_parse(to_identifier("x"))
5727        Identifier(this=x, quoted=False)
5728
5729    Args:
5730        sql_or_expression: the SQL code string or an expression
5731        into: the SQLGlot Expression to parse into
5732        dialect: the dialect used to parse the input expressions (in the case that an
5733            input expression is a SQL string).
5734        prefix: a string to prefix the sql with before it gets parsed
5735            (automatically includes a space)
5736        copy: whether to copy the expression.
5737        **opts: other options to use to parse the input expressions (again, in the case
5738            that an input expression is a SQL string).
5739
5740    Returns:
5741        Expression: the parsed or given expression.
5742    """
5743    if isinstance(sql_or_expression, Expression):
5744        if copy:
5745            return sql_or_expression.copy()
5746        return sql_or_expression
5747
5748    if sql_or_expression is None:
5749        raise ParseError("SQL cannot be None")
5750
5751    import sqlglot
5752
5753    sql = str(sql_or_expression)
5754    if prefix:
5755        sql = f"{prefix} {sql}"
5756
5757    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):
5768def maybe_copy(instance, copy=True):
5769    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:
5983def union(
5984    left: ExpOrStr,
5985    right: ExpOrStr,
5986    distinct: bool = True,
5987    dialect: DialectType = None,
5988    copy: bool = True,
5989    **opts,
5990) -> Union:
5991    """
5992    Initializes a syntax tree from one UNION expression.
5993
5994    Example:
5995        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5996        'SELECT * FROM foo UNION SELECT * FROM bla'
5997
5998    Args:
5999        left: the SQL code string corresponding to the left-hand side.
6000            If an `Expression` instance is passed, it will be used as-is.
6001        right: the SQL code string corresponding to the right-hand side.
6002            If an `Expression` instance is passed, it will be used as-is.
6003        distinct: set the DISTINCT flag if and only if this is true.
6004        dialect: the dialect used to parse the input expression.
6005        copy: whether to copy the expression.
6006        opts: other options to use to parse the input expressions.
6007
6008    Returns:
6009        The new Union instance.
6010    """
6011    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6012    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6013
6014    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:
6017def intersect(
6018    left: ExpOrStr,
6019    right: ExpOrStr,
6020    distinct: bool = True,
6021    dialect: DialectType = None,
6022    copy: bool = True,
6023    **opts,
6024) -> Intersect:
6025    """
6026    Initializes a syntax tree from one INTERSECT expression.
6027
6028    Example:
6029        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6030        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6031
6032    Args:
6033        left: the SQL code string corresponding to the left-hand side.
6034            If an `Expression` instance is passed, it will be used as-is.
6035        right: the SQL code string corresponding to the right-hand side.
6036            If an `Expression` instance is passed, it will be used as-is.
6037        distinct: set the DISTINCT flag if and only if this is true.
6038        dialect: the dialect used to parse the input expression.
6039        copy: whether to copy the expression.
6040        opts: other options to use to parse the input expressions.
6041
6042    Returns:
6043        The new Intersect instance.
6044    """
6045    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6046    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6047
6048    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:
6051def except_(
6052    left: ExpOrStr,
6053    right: ExpOrStr,
6054    distinct: bool = True,
6055    dialect: DialectType = None,
6056    copy: bool = True,
6057    **opts,
6058) -> Except:
6059    """
6060    Initializes a syntax tree from one EXCEPT expression.
6061
6062    Example:
6063        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6064        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6065
6066    Args:
6067        left: the SQL code string corresponding to the left-hand side.
6068            If an `Expression` instance is passed, it will be used as-is.
6069        right: the SQL code string corresponding to the right-hand side.
6070            If an `Expression` instance is passed, it will be used as-is.
6071        distinct: set the DISTINCT flag if and only if this is true.
6072        dialect: the dialect used to parse the input expression.
6073        copy: whether to copy the expression.
6074        opts: other options to use to parse the input expressions.
6075
6076    Returns:
6077        The new Except instance.
6078    """
6079    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6080    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6081
6082    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:
6085def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6086    """
6087    Initializes a syntax tree from one or multiple SELECT expressions.
6088
6089    Example:
6090        >>> select("col1", "col2").from_("tbl").sql()
6091        'SELECT col1, col2 FROM tbl'
6092
6093    Args:
6094        *expressions: the SQL code string to parse as the expressions of a
6095            SELECT statement. If an Expression instance is passed, this is used as-is.
6096        dialect: the dialect used to parse the input expressions (in the case that an
6097            input expression is a SQL string).
6098        **opts: other options to use to parse the input expressions (again, in the case
6099            that an input expression is a SQL string).
6100
6101    Returns:
6102        Select: the syntax tree for the SELECT statement.
6103    """
6104    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:
6107def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6108    """
6109    Initializes a syntax tree from a FROM expression.
6110
6111    Example:
6112        >>> from_("tbl").select("col1", "col2").sql()
6113        'SELECT col1, col2 FROM tbl'
6114
6115    Args:
6116        *expression: the SQL code string to parse as the FROM expressions of a
6117            SELECT statement. If an Expression instance is passed, this is used as-is.
6118        dialect: the dialect used to parse the input expression (in the case that the
6119            input expression is a SQL string).
6120        **opts: other options to use to parse the input expressions (again, in the case
6121            that the input expression is a SQL string).
6122
6123    Returns:
6124        Select: the syntax tree for the SELECT statement.
6125    """
6126    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:
6129def update(
6130    table: str | Table,
6131    properties: dict,
6132    where: t.Optional[ExpOrStr] = None,
6133    from_: t.Optional[ExpOrStr] = None,
6134    dialect: DialectType = None,
6135    **opts,
6136) -> Update:
6137    """
6138    Creates an update statement.
6139
6140    Example:
6141        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6142        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6143
6144    Args:
6145        *properties: dictionary of properties to set which are
6146            auto converted to sql objects eg None -> NULL
6147        where: sql conditional parsed into a WHERE statement
6148        from_: sql statement parsed into a FROM statement
6149        dialect: the dialect used to parse the input expressions.
6150        **opts: other options to use to parse the input expressions.
6151
6152    Returns:
6153        Update: the syntax tree for the UPDATE statement.
6154    """
6155    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6156    update_expr.set(
6157        "expressions",
6158        [
6159            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6160            for k, v in properties.items()
6161        ],
6162    )
6163    if from_:
6164        update_expr.set(
6165            "from",
6166            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6167        )
6168    if isinstance(where, Condition):
6169        where = Where(this=where)
6170    if where:
6171        update_expr.set(
6172            "where",
6173            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6174        )
6175    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:
6178def delete(
6179    table: ExpOrStr,
6180    where: t.Optional[ExpOrStr] = None,
6181    returning: t.Optional[ExpOrStr] = None,
6182    dialect: DialectType = None,
6183    **opts,
6184) -> Delete:
6185    """
6186    Builds a delete statement.
6187
6188    Example:
6189        >>> delete("my_table", where="id > 1").sql()
6190        'DELETE FROM my_table WHERE id > 1'
6191
6192    Args:
6193        where: sql conditional parsed into a WHERE statement
6194        returning: sql conditional parsed into a RETURNING statement
6195        dialect: the dialect used to parse the input expressions.
6196        **opts: other options to use to parse the input expressions.
6197
6198    Returns:
6199        Delete: the syntax tree for the DELETE statement.
6200    """
6201    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6202    if where:
6203        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6204    if returning:
6205        delete_expr = t.cast(
6206            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6207        )
6208    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:
6211def insert(
6212    expression: ExpOrStr,
6213    into: ExpOrStr,
6214    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6215    overwrite: t.Optional[bool] = None,
6216    returning: t.Optional[ExpOrStr] = None,
6217    dialect: DialectType = None,
6218    copy: bool = True,
6219    **opts,
6220) -> Insert:
6221    """
6222    Builds an INSERT statement.
6223
6224    Example:
6225        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6226        'INSERT INTO tbl VALUES (1, 2, 3)'
6227
6228    Args:
6229        expression: the sql string or expression of the INSERT statement
6230        into: the tbl to insert data to.
6231        columns: optionally the table's column names.
6232        overwrite: whether to INSERT OVERWRITE or not.
6233        returning: sql conditional parsed into a RETURNING statement
6234        dialect: the dialect used to parse the input expressions.
6235        copy: whether to copy the expression.
6236        **opts: other options to use to parse the input expressions.
6237
6238    Returns:
6239        Insert: the syntax tree for the INSERT statement.
6240    """
6241    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6242    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6243
6244    if columns:
6245        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6246
6247    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6248
6249    if returning:
6250        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6251
6252    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:
6255def condition(
6256    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6257) -> Condition:
6258    """
6259    Initialize a logical condition expression.
6260
6261    Example:
6262        >>> condition("x=1").sql()
6263        'x = 1'
6264
6265        This is helpful for composing larger logical syntax trees:
6266        >>> where = condition("x=1")
6267        >>> where = where.and_("y=1")
6268        >>> Select().from_("tbl").select("*").where(where).sql()
6269        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6270
6271    Args:
6272        *expression: the SQL code string to parse.
6273            If an Expression instance is passed, this is used as-is.
6274        dialect: the dialect used to parse the input expression (in the case that the
6275            input expression is a SQL string).
6276        copy: Whether to copy `expression` (only applies to expressions).
6277        **opts: other options to use to parse the input expressions (again, in the case
6278            that the input expression is a SQL string).
6279
6280    Returns:
6281        The new Condition instance
6282    """
6283    return maybe_parse(
6284        expression,
6285        into=Condition,
6286        dialect=dialect,
6287        copy=copy,
6288        **opts,
6289    )

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:
6292def and_(
6293    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6294) -> Condition:
6295    """
6296    Combine multiple conditions with an AND logical operator.
6297
6298    Example:
6299        >>> and_("x=1", and_("y=1", "z=1")).sql()
6300        'x = 1 AND (y = 1 AND z = 1)'
6301
6302    Args:
6303        *expressions: the SQL code strings to parse.
6304            If an Expression instance is passed, this is used as-is.
6305        dialect: the dialect used to parse the input expression.
6306        copy: whether to copy `expressions` (only applies to Expressions).
6307        **opts: other options to use to parse the input expressions.
6308
6309    Returns:
6310        And: the new condition
6311    """
6312    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:
6315def or_(
6316    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6317) -> Condition:
6318    """
6319    Combine multiple conditions with an OR logical operator.
6320
6321    Example:
6322        >>> or_("x=1", or_("y=1", "z=1")).sql()
6323        'x = 1 OR (y = 1 OR z = 1)'
6324
6325    Args:
6326        *expressions: the SQL code strings to parse.
6327            If an Expression instance is passed, this is used as-is.
6328        dialect: the dialect used to parse the input expression.
6329        copy: whether to copy `expressions` (only applies to Expressions).
6330        **opts: other options to use to parse the input expressions.
6331
6332    Returns:
6333        Or: the new condition
6334    """
6335    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:
6338def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6339    """
6340    Wrap a condition with a NOT operator.
6341
6342    Example:
6343        >>> not_("this_suit='black'").sql()
6344        "NOT this_suit = 'black'"
6345
6346    Args:
6347        expression: the SQL code string to parse.
6348            If an Expression instance is passed, this is used as-is.
6349        dialect: the dialect used to parse the input expression.
6350        copy: whether to copy the expression or not.
6351        **opts: other options to use to parse the input expressions.
6352
6353    Returns:
6354        The new condition.
6355    """
6356    this = condition(
6357        expression,
6358        dialect=dialect,
6359        copy=copy,
6360        **opts,
6361    )
6362    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:
6365def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6366    """
6367    Wrap an expression in parentheses.
6368
6369    Example:
6370        >>> paren("5 + 3").sql()
6371        '(5 + 3)'
6372
6373    Args:
6374        expression: the SQL code string to parse.
6375            If an Expression instance is passed, this is used as-is.
6376        copy: whether to copy the expression or not.
6377
6378    Returns:
6379        The wrapped expression.
6380    """
6381    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):
6397def to_identifier(name, quoted=None, copy=True):
6398    """Builds an identifier.
6399
6400    Args:
6401        name: The name to turn into an identifier.
6402        quoted: Whether to force quote the identifier.
6403        copy: Whether to copy name if it's an Identifier.
6404
6405    Returns:
6406        The identifier ast node.
6407    """
6408
6409    if name is None:
6410        return None
6411
6412    if isinstance(name, Identifier):
6413        identifier = maybe_copy(name, copy)
6414    elif isinstance(name, str):
6415        identifier = Identifier(
6416            this=name,
6417            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6418        )
6419    else:
6420        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6421    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:
6424def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6425    """
6426    Parses a given string into an identifier.
6427
6428    Args:
6429        name: The name to parse into an identifier.
6430        dialect: The dialect to parse against.
6431
6432    Returns:
6433        The identifier ast node.
6434    """
6435    try:
6436        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6437    except ParseError:
6438        expression = to_identifier(name)
6439
6440    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:
6446def to_interval(interval: str | Literal) -> Interval:
6447    """Builds an interval expression from a string like '1 day' or '5 months'."""
6448    if isinstance(interval, Literal):
6449        if not interval.is_string:
6450            raise ValueError("Invalid interval string.")
6451
6452        interval = interval.this
6453
6454    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6455
6456    if not interval_parts:
6457        raise ValueError("Invalid interval string.")
6458
6459    return Interval(
6460        this=Literal.string(interval_parts.group(1)),
6461        unit=Var(this=interval_parts.group(2).upper()),
6462    )

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]:
6473def to_table(
6474    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6475) -> t.Optional[Table]:
6476    """
6477    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6478    If a table is passed in then that table is returned.
6479
6480    Args:
6481        sql_path: a `[catalog].[schema].[table]` string.
6482        dialect: the source dialect according to which the table name will be parsed.
6483        copy: Whether to copy a table if it is passed in.
6484        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6485
6486    Returns:
6487        A table expression.
6488    """
6489    if sql_path is None or isinstance(sql_path, Table):
6490        return maybe_copy(sql_path, copy=copy)
6491    if not isinstance(sql_path, str):
6492        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6493
6494    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6495    if table:
6496        for k, v in kwargs.items():
6497            table.set(k, v)
6498
6499    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:
6502def to_column(sql_path: str | Column, **kwargs) -> Column:
6503    """
6504    Create a column from a `[table].[column]` sql path. Schema is optional.
6505
6506    If a column is passed in then that column is returned.
6507
6508    Args:
6509        sql_path: `[table].[column]` string
6510    Returns:
6511        Table: A column expression
6512    """
6513    if sql_path is None or isinstance(sql_path, Column):
6514        return sql_path
6515    if not isinstance(sql_path, str):
6516        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6517    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):
6520def alias_(
6521    expression: ExpOrStr,
6522    alias: t.Optional[str | Identifier],
6523    table: bool | t.Sequence[str | Identifier] = False,
6524    quoted: t.Optional[bool] = None,
6525    dialect: DialectType = None,
6526    copy: bool = True,
6527    **opts,
6528):
6529    """Create an Alias expression.
6530
6531    Example:
6532        >>> alias_('foo', 'bar').sql()
6533        'foo AS bar'
6534
6535        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6536        '(SELECT 1, 2) AS bar(a, b)'
6537
6538    Args:
6539        expression: the SQL code strings to parse.
6540            If an Expression instance is passed, this is used as-is.
6541        alias: the alias name to use. If the name has
6542            special characters it is quoted.
6543        table: Whether to create a table alias, can also be a list of columns.
6544        quoted: whether to quote the alias
6545        dialect: the dialect used to parse the input expression.
6546        copy: Whether to copy the expression.
6547        **opts: other options to use to parse the input expressions.
6548
6549    Returns:
6550        Alias: the aliased expression
6551    """
6552    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6553    alias = to_identifier(alias, quoted=quoted)
6554
6555    if table:
6556        table_alias = TableAlias(this=alias)
6557        exp.set("alias", table_alias)
6558
6559        if not isinstance(table, bool):
6560            for column in table:
6561                table_alias.append("columns", to_identifier(column, quoted=quoted))
6562
6563        return exp
6564
6565    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6566    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6567    # for the complete Window expression.
6568    #
6569    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6570
6571    if "alias" in exp.arg_types and not isinstance(exp, Window):
6572        exp.set("alias", alias)
6573        return exp
6574    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:
6577def subquery(
6578    expression: ExpOrStr,
6579    alias: t.Optional[Identifier | str] = None,
6580    dialect: DialectType = None,
6581    **opts,
6582) -> Select:
6583    """
6584    Build a subquery expression.
6585
6586    Example:
6587        >>> subquery('select x from tbl', 'bar').select('x').sql()
6588        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6589
6590    Args:
6591        expression: the SQL code strings to parse.
6592            If an Expression instance is passed, this is used as-is.
6593        alias: the alias name to use.
6594        dialect: the dialect used to parse the input expression.
6595        **opts: other options to use to parse the input expressions.
6596
6597    Returns:
6598        A new Select instance with the subquery expression included.
6599    """
6600
6601    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6602    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):
6633def column(
6634    col,
6635    table=None,
6636    db=None,
6637    catalog=None,
6638    *,
6639    fields=None,
6640    quoted=None,
6641    copy=True,
6642):
6643    """
6644    Build a Column.
6645
6646    Args:
6647        col: Column name.
6648        table: Table name.
6649        db: Database name.
6650        catalog: Catalog name.
6651        fields: Additional fields using dots.
6652        quoted: Whether to force quotes on the column's identifiers.
6653        copy: Whether to copy identifiers if passed in.
6654
6655    Returns:
6656        The new Column instance.
6657    """
6658    this = Column(
6659        this=to_identifier(col, quoted=quoted, copy=copy),
6660        table=to_identifier(table, quoted=quoted, copy=copy),
6661        db=to_identifier(db, quoted=quoted, copy=copy),
6662        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6663    )
6664
6665    if fields:
6666        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6667    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:
6670def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6671    """Cast an expression to a data type.
6672
6673    Example:
6674        >>> cast('x + 1', 'int').sql()
6675        'CAST(x + 1 AS INT)'
6676
6677    Args:
6678        expression: The expression to cast.
6679        to: The datatype to cast to.
6680        copy: Whether to copy the supplied expressions.
6681
6682    Returns:
6683        The new Cast instance.
6684    """
6685    expression = maybe_parse(expression, copy=copy, **opts)
6686    data_type = DataType.build(to, copy=copy, **opts)
6687    expression = Cast(this=expression, to=data_type)
6688    expression.type = data_type
6689    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:
6692def table_(
6693    table: Identifier | str,
6694    db: t.Optional[Identifier | str] = None,
6695    catalog: t.Optional[Identifier | str] = None,
6696    quoted: t.Optional[bool] = None,
6697    alias: t.Optional[Identifier | str] = None,
6698) -> Table:
6699    """Build a Table.
6700
6701    Args:
6702        table: Table name.
6703        db: Database name.
6704        catalog: Catalog name.
6705        quote: Whether to force quotes on the table's identifiers.
6706        alias: Table's alias.
6707
6708    Returns:
6709        The new Table instance.
6710    """
6711    return Table(
6712        this=to_identifier(table, quoted=quoted) if table else None,
6713        db=to_identifier(db, quoted=quoted) if db else None,
6714        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6715        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6716    )

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:
6719def values(
6720    values: t.Iterable[t.Tuple[t.Any, ...]],
6721    alias: t.Optional[str] = None,
6722    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6723) -> Values:
6724    """Build VALUES statement.
6725
6726    Example:
6727        >>> values([(1, '2')]).sql()
6728        "VALUES (1, '2')"
6729
6730    Args:
6731        values: values statements that will be converted to SQL
6732        alias: optional alias
6733        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6734         If either are provided then an alias is also required.
6735
6736    Returns:
6737        Values: the Values expression object
6738    """
6739    if columns and not alias:
6740        raise ValueError("Alias is required when providing columns")
6741
6742    return Values(
6743        expressions=[convert(tup) for tup in values],
6744        alias=(
6745            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6746            if columns
6747            else (TableAlias(this=to_identifier(alias)) if alias else None)
6748        ),
6749    )

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:
6752def var(name: t.Optional[ExpOrStr]) -> Var:
6753    """Build a SQL variable.
6754
6755    Example:
6756        >>> repr(var('x'))
6757        'Var(this=x)'
6758
6759        >>> repr(var(column('x', table='y')))
6760        'Var(this=x)'
6761
6762    Args:
6763        name: The name of the var or an expression who's name will become the var.
6764
6765    Returns:
6766        The new variable node.
6767    """
6768    if not name:
6769        raise ValueError("Cannot convert empty name into var.")
6770
6771    if isinstance(name, Expression):
6772        name = name.name
6773    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:
6776def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6777    """Build ALTER TABLE... RENAME... expression
6778
6779    Args:
6780        old_name: The old name of the table
6781        new_name: The new name of the table
6782
6783    Returns:
6784        Alter table expression
6785    """
6786    old_table = to_table(old_name)
6787    new_table = to_table(new_name)
6788    return AlterTable(
6789        this=old_table,
6790        actions=[
6791            RenameTable(this=new_table),
6792        ],
6793    )

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:
6796def rename_column(
6797    table_name: str | Table,
6798    old_column_name: str | Column,
6799    new_column_name: str | Column,
6800    exists: t.Optional[bool] = None,
6801) -> AlterTable:
6802    """Build ALTER TABLE... RENAME COLUMN... expression
6803
6804    Args:
6805        table_name: Name of the table
6806        old_column: The old name of the column
6807        new_column: The new name of the column
6808        exists: Whether to add the `IF EXISTS` clause
6809
6810    Returns:
6811        Alter table expression
6812    """
6813    table = to_table(table_name)
6814    old_column = to_column(old_column_name)
6815    new_column = to_column(new_column_name)
6816    return AlterTable(
6817        this=table,
6818        actions=[
6819            RenameColumn(this=old_column, to=new_column, exists=exists),
6820        ],
6821    )

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:
6824def convert(value: t.Any, copy: bool = False) -> Expression:
6825    """Convert a python value into an expression object.
6826
6827    Raises an error if a conversion is not possible.
6828
6829    Args:
6830        value: A python object.
6831        copy: Whether to copy `value` (only applies to Expressions and collections).
6832
6833    Returns:
6834        Expression: the equivalent expression object.
6835    """
6836    if isinstance(value, Expression):
6837        return maybe_copy(value, copy)
6838    if isinstance(value, str):
6839        return Literal.string(value)
6840    if isinstance(value, bool):
6841        return Boolean(this=value)
6842    if value is None or (isinstance(value, float) and math.isnan(value)):
6843        return null()
6844    if isinstance(value, numbers.Number):
6845        return Literal.number(value)
6846    if isinstance(value, datetime.datetime):
6847        datetime_literal = Literal.string(
6848            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6849        )
6850        return TimeStrToTime(this=datetime_literal)
6851    if isinstance(value, datetime.date):
6852        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6853        return DateStrToDate(this=date_literal)
6854    if isinstance(value, tuple):
6855        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6856    if isinstance(value, list):
6857        return Array(expressions=[convert(v, copy=copy) for v in value])
6858    if isinstance(value, dict):
6859        return Map(
6860            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6861            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6862        )
6863    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:
6866def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6867    """
6868    Replace children of an expression with the result of a lambda fun(child) -> exp.
6869    """
6870    for k, v in expression.args.items():
6871        is_list_arg = type(v) is list
6872
6873        child_nodes = v if is_list_arg else [v]
6874        new_child_nodes = []
6875
6876        for cn in child_nodes:
6877            if isinstance(cn, Expression):
6878                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6879                    new_child_nodes.append(child_node)
6880                    child_node.parent = expression
6881                    child_node.arg_key = k
6882            else:
6883                new_child_nodes.append(cn)
6884
6885        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]:
6888def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6889    """
6890    Return all table names referenced through columns in an expression.
6891
6892    Example:
6893        >>> import sqlglot
6894        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6895        ['a', 'c']
6896
6897    Args:
6898        expression: expression to find table names.
6899        exclude: a table name to exclude
6900
6901    Returns:
6902        A list of unique names.
6903    """
6904    return {
6905        table
6906        for table in (column.table for column in expression.find_all(Column))
6907        if table and table != exclude
6908    }

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:
6911def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6912    """Get the full name of a table as a string.
6913
6914    Args:
6915        table: Table expression node or string.
6916        dialect: The dialect to generate the table name for.
6917        identify: Determines when an identifier should be quoted. Possible values are:
6918            False (default): Never quote, except in cases where it's mandatory by the dialect.
6919            True: Always quote.
6920
6921    Examples:
6922        >>> from sqlglot import exp, parse_one
6923        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6924        'a.b.c'
6925
6926    Returns:
6927        The table name.
6928    """
6929
6930    table = maybe_parse(table, into=Table, dialect=dialect)
6931
6932    if not table:
6933        raise ValueError(f"Cannot parse {table}")
6934
6935    return ".".join(
6936        (
6937            part.sql(dialect=dialect, identify=True, copy=False)
6938            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6939            else part.name
6940        )
6941        for part in table.parts
6942    )

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:
6945def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6946    """Returns a case normalized table name without quotes.
6947
6948    Args:
6949        table: the table to normalize
6950        dialect: the dialect to use for normalization rules
6951        copy: whether to copy the expression.
6952
6953    Examples:
6954        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6955        'A-B.c'
6956    """
6957    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6958
6959    return ".".join(
6960        p.name
6961        for p in normalize_identifiers(
6962            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6963        ).parts
6964    )

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:
6967def replace_tables(
6968    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6969) -> E:
6970    """Replace all tables in expression according to the mapping.
6971
6972    Args:
6973        expression: expression node to be transformed and replaced.
6974        mapping: mapping of table names.
6975        dialect: the dialect of the mapping table
6976        copy: whether to copy the expression.
6977
6978    Examples:
6979        >>> from sqlglot import exp, parse_one
6980        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6981        'SELECT * FROM c /* a.b */'
6982
6983    Returns:
6984        The mapped expression.
6985    """
6986
6987    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6988
6989    def _replace_tables(node: Expression) -> Expression:
6990        if isinstance(node, Table):
6991            original = normalize_table_name(node, dialect=dialect)
6992            new_name = mapping.get(original)
6993
6994            if new_name:
6995                table = to_table(
6996                    new_name,
6997                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6998                    dialect=dialect,
6999                )
7000                table.add_comments([original])
7001                return table
7002        return node
7003
7004    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:
7007def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7008    """Replace placeholders in an expression.
7009
7010    Args:
7011        expression: expression node to be transformed and replaced.
7012        args: positional names that will substitute unnamed placeholders in the given order.
7013        kwargs: keyword arguments that will substitute named placeholders.
7014
7015    Examples:
7016        >>> from sqlglot import exp, parse_one
7017        >>> replace_placeholders(
7018        ...     parse_one("select * from :tbl where ? = ?"),
7019        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7020        ... ).sql()
7021        "SELECT * FROM foo WHERE str_col = 'b'"
7022
7023    Returns:
7024        The mapped expression.
7025    """
7026
7027    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7028        if isinstance(node, Placeholder):
7029            if node.name:
7030                new_name = kwargs.get(node.name)
7031                if new_name is not None:
7032                    return convert(new_name)
7033            else:
7034                try:
7035                    return convert(next(args))
7036                except StopIteration:
7037                    pass
7038        return node
7039
7040    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:
7043def expand(
7044    expression: Expression,
7045    sources: t.Dict[str, Query],
7046    dialect: DialectType = None,
7047    copy: bool = True,
7048) -> Expression:
7049    """Transforms an expression by expanding all referenced sources into subqueries.
7050
7051    Examples:
7052        >>> from sqlglot import parse_one
7053        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7054        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7055
7056        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7057        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7058
7059    Args:
7060        expression: The expression to expand.
7061        sources: A dictionary of name to Queries.
7062        dialect: The dialect of the sources dict.
7063        copy: Whether to copy the expression during transformation. Defaults to True.
7064
7065    Returns:
7066        The transformed expression.
7067    """
7068    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7069
7070    def _expand(node: Expression):
7071        if isinstance(node, Table):
7072            name = normalize_table_name(node, dialect=dialect)
7073            source = sources.get(name)
7074            if source:
7075                subquery = source.subquery(node.alias or name)
7076                subquery.comments = [f"source: {name}"]
7077                return subquery.transform(_expand, copy=False)
7078        return node
7079
7080    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:
7083def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7084    """
7085    Returns a Func expression.
7086
7087    Examples:
7088        >>> func("abs", 5).sql()
7089        'ABS(5)'
7090
7091        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7092        'CAST(5 AS DOUBLE)'
7093
7094    Args:
7095        name: the name of the function to build.
7096        args: the args used to instantiate the function of interest.
7097        copy: whether to copy the argument expressions.
7098        dialect: the source dialect.
7099        kwargs: the kwargs used to instantiate the function of interest.
7100
7101    Note:
7102        The arguments `args` and `kwargs` are mutually exclusive.
7103
7104    Returns:
7105        An instance of the function of interest, or an anonymous function, if `name` doesn't
7106        correspond to an existing `sqlglot.expressions.Func` class.
7107    """
7108    if args and kwargs:
7109        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7110
7111    from sqlglot.dialects.dialect import Dialect
7112
7113    dialect = Dialect.get_or_raise(dialect)
7114
7115    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7116    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7117
7118    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7119    if constructor:
7120        if converted:
7121            if "dialect" in constructor.__code__.co_varnames:
7122                function = constructor(converted, dialect=dialect)
7123            else:
7124                function = constructor(converted)
7125        elif constructor.__name__ == "from_arg_list":
7126            function = constructor.__self__(**kwargs)  # type: ignore
7127        else:
7128            constructor = FUNCTION_BY_NAME.get(name.upper())
7129            if constructor:
7130                function = constructor(**kwargs)
7131            else:
7132                raise ValueError(
7133                    f"Unable to convert '{name}' into a Func. Either manually construct "
7134                    "the Func expression of interest or parse the function call."
7135                )
7136    else:
7137        kwargs = kwargs or {"expressions": converted}
7138        function = Anonymous(this=name, **kwargs)
7139
7140    for error_message in function.error_messages(converted):
7141        raise ValueError(error_message)
7142
7143    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:
7146def case(
7147    expression: t.Optional[ExpOrStr] = None,
7148    **opts,
7149) -> Case:
7150    """
7151    Initialize a CASE statement.
7152
7153    Example:
7154        case().when("a = 1", "foo").else_("bar")
7155
7156    Args:
7157        expression: Optionally, the input expression (not all dialects support this)
7158        **opts: Extra keyword arguments for parsing `expression`
7159    """
7160    if expression is not None:
7161        this = maybe_parse(expression, **opts)
7162    else:
7163        this = None
7164    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:
7167def cast_unless(
7168    expression: ExpOrStr,
7169    to: DATA_TYPE,
7170    *types: DATA_TYPE,
7171    **opts: t.Any,
7172) -> Expression | Cast:
7173    """
7174    Cast an expression to a data type unless it is a specified type.
7175
7176    Args:
7177        expression: The expression to cast.
7178        to: The data type to cast to.
7179        **types: The types to exclude from casting.
7180        **opts: Extra keyword arguments for parsing `expression`
7181    """
7182    expr = maybe_parse(expression, **opts)
7183    if expr.is_type(*types):
7184        return expr
7185    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:
7188def array(
7189    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7190) -> Array:
7191    """
7192    Returns an array.
7193
7194    Examples:
7195        >>> array(1, 'x').sql()
7196        'ARRAY(1, x)'
7197
7198    Args:
7199        expressions: the expressions to add to the array.
7200        copy: whether to copy the argument expressions.
7201        dialect: the source dialect.
7202        kwargs: the kwargs used to instantiate the function of interest.
7203
7204    Returns:
7205        An array expression.
7206    """
7207    return Array(
7208        expressions=[
7209            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7210            for expression in expressions
7211        ]
7212    )

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:
7215def tuple_(
7216    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7217) -> Tuple:
7218    """
7219    Returns an tuple.
7220
7221    Examples:
7222        >>> tuple_(1, 'x').sql()
7223        '(1, x)'
7224
7225    Args:
7226        expressions: the expressions to add to the tuple.
7227        copy: whether to copy the argument expressions.
7228        dialect: the source dialect.
7229        kwargs: the kwargs used to instantiate the function of interest.
7230
7231    Returns:
7232        A tuple expression.
7233    """
7234    return Tuple(
7235        expressions=[
7236            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7237            for expression in expressions
7238        ]
7239    )

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:
7242def true() -> Boolean:
7243    """
7244    Returns a true Boolean expression.
7245    """
7246    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7249def false() -> Boolean:
7250    """
7251    Returns a false Boolean expression.
7252    """
7253    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7256def null() -> Null:
7257    """
7258    Returns a Null expression.
7259    """
7260    return Null()

Returns a Null expression.