Edit on GitHub

Expressions

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

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


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

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

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
 97    def __init__(self, **args: t.Any):
 98        self.args: t.Dict[str, t.Any] = args
 99        self.parent: t.Optional[Expression] = None
100        self.arg_key: t.Optional[str] = None
101        self.comments: t.Optional[t.List[str]] = None
102        self._type: t.Optional[DataType] = None
103        self._meta: t.Optional[t.Dict[str, t.Any]] = None
104        self._hash: t.Optional[int] = None
105
106        for arg_key, value in self.args.items():
107            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
comments: Optional[List[str]]
hashable_args: Any
112    @property
113    def hashable_args(self) -> t.Any:
114        return frozenset(
115            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
116            for k, v in self.args.items()
117            if not (v is None or v is False or (type(v) is list and not v))
118        )
this: Any
126    @property
127    def this(self) -> t.Any:
128        """
129        Retrieves the argument with key "this".
130        """
131        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
147    def text(self, key) -> str:
148        """
149        Returns a textual representation of the argument corresponding to "key". This can only be used
150        for args that are strings or leaf Expression instances, such as identifiers and literals.
151        """
152        field = self.args.get(key)
153        if isinstance(field, str):
154            return field
155        if isinstance(field, (Identifier, Literal, Var)):
156            return field.this
157        if isinstance(field, (Star, Null)):
158            return field.name
159        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
161    @property
162    def is_string(self) -> bool:
163        """
164        Checks whether a Literal expression is a string.
165        """
166        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
196    @property
197    def alias_column_names(self) -> t.List[str]:
198        table_alias = self.args.get("alias")
199        if not table_alias:
200            return []
201        return [c.name for c in table_alias.args.get("columns") or []]
name: str
203    @property
204    def name(self) -> str:
205        return self.text("this")
alias_or_name: str
207    @property
208    def alias_or_name(self) -> str:
209        return self.alias or self.name
output_name: str
211    @property
212    def output_name(self) -> str:
213        """
214        Name of the output column if this expression is a selection.
215
216        If the Expression has no output name, an empty string is returned.
217
218        Example:
219            >>> from sqlglot import parse_one
220            >>> parse_one("SELECT a").expressions[0].output_name
221            'a'
222            >>> parse_one("SELECT b AS c").expressions[0].output_name
223            'c'
224            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
225            ''
226        """
227        return ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
229    @property
230    def type(self) -> t.Optional[DataType]:
231        return self._type
def is_type(self, *dtypes) -> bool:
239    def is_type(self, *dtypes) -> bool:
240        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
242    def is_leaf(self) -> bool:
243        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
245    @property
246    def meta(self) -> t.Dict[str, t.Any]:
247        if self._meta is None:
248            self._meta = {}
249        return self._meta
def copy(self):
264    def copy(self):
265        """
266        Returns a deep copy of the expression.
267        """
268        new = deepcopy(self)
269        new.parent = self.parent
270        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
272    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
273        if self.comments is None:
274            self.comments = []
275        if comments:
276            for comment in comments:
277                _, *meta = comment.split(SQLGLOT_META)
278                if meta:
279                    for kv in "".join(meta).split(","):
280                        k, *v = kv.split("=")
281                        value = v[0].strip() if v else True
282                        self.meta[k.strip()] = value
283                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
285    def append(self, arg_key: str, value: t.Any) -> None:
286        """
287        Appends value to arg_key if it's a list or sets it as a new list.
288
289        Args:
290            arg_key (str): name of the list expression arg
291            value (Any): value to append to the list
292        """
293        if not isinstance(self.args.get(arg_key), list):
294            self.args[arg_key] = []
295        self.args[arg_key].append(value)
296        self._set_parent(arg_key, value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any) -> None:
298    def set(self, arg_key: str, value: t.Any) -> None:
299        """
300        Sets arg_key to value.
301
302        Args:
303            arg_key: name of the expression arg.
304            value: value to set the arg to.
305        """
306        if value is None:
307            self.args.pop(arg_key, None)
308            return
309
310        self.args[arg_key] = value
311        self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int
323    @property
324    def depth(self) -> int:
325        """
326        Returns the depth of this tree.
327        """
328        if self.parent:
329            return self.parent.depth + 1
330        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
332    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
333        """Yields the key and expression for all arguments, exploding list args."""
334        for k, vs in self.args.items():
335            if type(vs) is list:
336                for v in vs:
337                    if hasattr(v, "parent"):
338                        yield k, v
339            else:
340                if hasattr(vs, "parent"):
341                    yield k, vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
343    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
344        """
345        Returns the first node in this tree which matches at least one of
346        the specified types.
347
348        Args:
349            expression_types: the expression type(s) to match.
350            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
351
352        Returns:
353            The node which matches the criteria or None if no such node was found.
354        """
355        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
357    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
358        """
359        Returns a generator object which visits all nodes in this tree and only
360        yields those that match at least one of the specified expression types.
361
362        Args:
363            expression_types: the expression type(s) to match.
364            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
365
366        Returns:
367            The generator object.
368        """
369        for expression, *_ in self.walk(bfs=bfs):
370            if isinstance(expression, expression_types):
371                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
373    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
374        """
375        Returns a nearest parent matching expression_types.
376
377        Args:
378            expression_types: the expression type(s) to match.
379
380        Returns:
381            The parent node.
382        """
383        ancestor = self.parent
384        while ancestor and not isinstance(ancestor, expression_types):
385            ancestor = ancestor.parent
386        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
409    def walk(self, bfs=True, prune=None):
410        """
411        Returns a generator object which visits all nodes in this tree.
412
413        Args:
414            bfs (bool): if set to True the BFS traversal order will be applied,
415                otherwise the DFS traversal will be used instead.
416            prune ((node, parent, arg_key) -> bool): callable that returns True if
417                the generator should stop traversing this branch of the tree.
418
419        Returns:
420            the generator object.
421        """
422        if bfs:
423            yield from self.bfs(prune=prune)
424        else:
425            yield from self.dfs(prune=prune)

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

Arguments:
  • bfs (bool): if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune ((node, parent, arg_key) -> bool): callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs(self, parent=None, key=None, prune=None):
427    def dfs(self, parent=None, key=None, prune=None):
428        """
429        Returns a generator object which visits all nodes in this tree in
430        the DFS (Depth-first) order.
431
432        Returns:
433            The generator object.
434        """
435        parent = parent or self.parent
436        yield self, parent, key
437        if prune and prune(self, parent, key):
438            return
439
440        for k, v in self.iter_expressions():
441            yield from v.dfs(self, k, prune)

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

Returns:

The generator object.

def bfs(self, prune=None):
443    def bfs(self, prune=None):
444        """
445        Returns a generator object which visits all nodes in this tree in
446        the BFS (Breadth-first) order.
447
448        Returns:
449            The generator object.
450        """
451        queue = deque([(self, self.parent, None)])
452
453        while queue:
454            item, parent, key = queue.popleft()
455
456            yield item, parent, key
457            if prune and prune(item, parent, key):
458                continue
459
460            for k, v in item.iter_expressions():
461                queue.append((v, item, k))

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

Returns:

The generator object.

def unnest(self):
463    def unnest(self):
464        """
465        Returns the first non parenthesis child or self.
466        """
467        expression = self
468        while type(expression) is Paren:
469            expression = expression.this
470        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
486    def flatten(self, unnest=True):
487        """
488        Returns a generator which yields child nodes whose parents are the same class.
489
490        A AND B AND C -> [A, B, C]
491        """
492        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and type(n) is not self.__class__):
493            if type(node) is not self.__class__:
494                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
502    def to_s(self) -> str:
503        """
504        Same as __repr__, but includes additional information which can be useful
505        for debugging, like empty or missing args and the AST nodes' object IDs.
506        """
507        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
509    def sql(self, dialect: DialectType = None, **opts) -> str:
510        """
511        Returns SQL string representation of this tree.
512
513        Args:
514            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
515            opts: other `sqlglot.generator.Generator` options.
516
517        Returns:
518            The SQL string.
519        """
520        from sqlglot.dialects import Dialect
521
522        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform(self, fun, *args, copy=True, **kwargs):
524    def transform(self, fun, *args, copy=True, **kwargs):
525        """
526        Recursively visits all tree nodes (excluding already transformed ones)
527        and applies the given transformation function to each node.
528
529        Args:
530            fun (function): a function which takes a node as an argument and returns a
531                new transformed node or the same node without modifications. If the function
532                returns None, then the corresponding node will be removed from the syntax tree.
533            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
534                modified in place.
535
536        Returns:
537            The transformed tree.
538        """
539        node = self.copy() if copy else self
540        new_node = fun(node, *args, **kwargs)
541
542        if new_node is None or not isinstance(new_node, Expression):
543            return new_node
544        if new_node is not node:
545            new_node.parent = node.parent
546            return new_node
547
548        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
549        return new_node

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

Arguments:
  • fun (function): a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy (bool): if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
657    @classmethod
658    def load(cls, obj):
659        """
660        Load a dict (as returned by `Expression.dump`) into an Expression instance.
661        """
662        from sqlglot.serde import load
663
664        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:
666    def and_(
667        self,
668        *expressions: t.Optional[ExpOrStr],
669        dialect: DialectType = None,
670        copy: bool = True,
671        **opts,
672    ) -> Condition:
673        """
674        AND this condition with one or multiple expressions.
675
676        Example:
677            >>> condition("x=1").and_("y=1").sql()
678            'x = 1 AND y = 1'
679
680        Args:
681            *expressions: the SQL code strings to parse.
682                If an `Expression` instance is passed, it will be used as-is.
683            dialect: the dialect used to parse the input expression.
684            copy: whether to copy the involved expressions (only applies to Expressions).
685            opts: other options to use to parse the input expressions.
686
687        Returns:
688            The new And condition.
689        """
690        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:
692    def or_(
693        self,
694        *expressions: t.Optional[ExpOrStr],
695        dialect: DialectType = None,
696        copy: bool = True,
697        **opts,
698    ) -> Condition:
699        """
700        OR this condition with one or multiple expressions.
701
702        Example:
703            >>> condition("x=1").or_("y=1").sql()
704            'x = 1 OR y = 1'
705
706        Args:
707            *expressions: the SQL code strings to parse.
708                If an `Expression` instance is passed, it will be used as-is.
709            dialect: the dialect used to parse the input expression.
710            copy: whether to copy the involved expressions (only applies to Expressions).
711            opts: other options to use to parse the input expressions.
712
713        Returns:
714            The new Or condition.
715        """
716        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):
718    def not_(self, copy: bool = True):
719        """
720        Wrap this condition with NOT.
721
722        Example:
723            >>> condition("x=1").not_().sql()
724            'NOT x = 1'
725
726        Args:
727            copy: whether to copy this object.
728
729        Returns:
730            The new Not instance.
731        """
732        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:
734    def as_(
735        self,
736        alias: str | Identifier,
737        quoted: t.Optional[bool] = None,
738        dialect: DialectType = None,
739        copy: bool = True,
740        **opts,
741    ) -> Alias:
742        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:
767    def isin(
768        self,
769        *expressions: t.Any,
770        query: t.Optional[ExpOrStr] = None,
771        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
772        copy: bool = True,
773        **opts,
774    ) -> In:
775        return In(
776            this=maybe_copy(self, copy),
777            expressions=[convert(e, copy=copy) for e in expressions],
778            query=maybe_parse(query, copy=copy, **opts) if query else None,
779            unnest=(
780                Unnest(
781                    expressions=[
782                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
783                        for e in ensure_list(unnest)
784                    ]
785                )
786                if unnest
787                else None
788            ),
789        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
791    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
792        return Between(
793            this=maybe_copy(self, copy),
794            low=convert(low, copy=copy, **opts),
795            high=convert(high, copy=copy, **opts),
796        )
def is_( self, other: Union[str, Expression]) -> Is:
798    def is_(self, other: ExpOrStr) -> Is:
799        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
801    def like(self, other: ExpOrStr) -> Like:
802        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
804    def ilike(self, other: ExpOrStr) -> ILike:
805        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
807    def eq(self, other: t.Any) -> EQ:
808        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
810    def neq(self, other: t.Any) -> NEQ:
811        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
813    def rlike(self, other: ExpOrStr) -> RegexpLike:
814        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
816    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
817        div = self._binop(Div, other)
818        div.args["typed"] = typed
819        div.args["safe"] = safe
820        return div
def desc(self, nulls_first: bool = False) -> Ordered:
822    def desc(self, nulls_first: bool = False) -> Ordered:
823        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):
906class Condition(Expression):
907    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

Returns the query's projections.

named_selects: List[str]
983    @property
984    def named_selects(self) -> t.List[str]:
985        """Returns the output names of the query's projections."""
986        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:
 988    def select(
 989        self,
 990        *expressions: t.Optional[ExpOrStr],
 991        append: bool = True,
 992        dialect: DialectType = None,
 993        copy: bool = True,
 994        **opts,
 995    ) -> Query:
 996        """
 997        Append to or set the SELECT expressions.
 998
 999        Example:
1000            >>> Select().select("x", "y").sql()
1001            'SELECT x, y'
1002
1003        Args:
1004            *expressions: the SQL code strings to parse.
1005                If an `Expression` instance is passed, it will be used as-is.
1006            append: if `True`, add to any existing expressions.
1007                Otherwise, this resets the expressions.
1008            dialect: the dialect used to parse the input expressions.
1009            copy: if `False`, modify this expression instance in-place.
1010            opts: other options to use to parse the input expressions.
1011
1012        Returns:
1013            The modified Query expression.
1014        """
1015        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:
1017    def with_(
1018        self,
1019        alias: ExpOrStr,
1020        as_: ExpOrStr,
1021        recursive: t.Optional[bool] = None,
1022        append: bool = True,
1023        dialect: DialectType = None,
1024        copy: bool = True,
1025        **opts,
1026    ) -> Query:
1027        """
1028        Append to or set the common table expressions.
1029
1030        Example:
1031            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1032            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1033
1034        Args:
1035            alias: the SQL code string to parse as the table name.
1036                If an `Expression` instance is passed, this is used as-is.
1037            as_: the SQL code string to parse as the table expression.
1038                If an `Expression` instance is passed, it will be used as-is.
1039            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1040            append: if `True`, add to any existing expressions.
1041                Otherwise, this resets the expressions.
1042            dialect: the dialect used to parse the input expression.
1043            copy: if `False`, modify this expression instance in-place.
1044            opts: other options to use to parse the input expressions.
1045
1046        Returns:
1047            The modified expression.
1048        """
1049        return _apply_cte_builder(
1050            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1051        )

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:
1053    def union(
1054        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1055    ) -> Union:
1056        """
1057        Builds a UNION expression.
1058
1059        Example:
1060            >>> import sqlglot
1061            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1062            'SELECT * FROM foo UNION SELECT * FROM bla'
1063
1064        Args:
1065            expression: the SQL code string.
1066                If an `Expression` instance is passed, it will be used as-is.
1067            distinct: set the DISTINCT flag if and only if this is true.
1068            dialect: the dialect used to parse the input expression.
1069            opts: other options to use to parse the input expressions.
1070
1071        Returns:
1072            The new Union expression.
1073        """
1074        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:
1076    def intersect(
1077        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1078    ) -> Intersect:
1079        """
1080        Builds an INTERSECT expression.
1081
1082        Example:
1083            >>> import sqlglot
1084            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1085            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1086
1087        Args:
1088            expression: the SQL code string.
1089                If an `Expression` instance is passed, it will be used as-is.
1090            distinct: set the DISTINCT flag if and only if this is true.
1091            dialect: the dialect used to parse the input expression.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The new Intersect expression.
1096        """
1097        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:
1099    def except_(
1100        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1101    ) -> Except:
1102        """
1103        Builds an EXCEPT expression.
1104
1105        Example:
1106            >>> import sqlglot
1107            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1108            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1109
1110        Args:
1111            expression: the SQL code string.
1112                If an `Expression` instance is passed, it will be used as-is.
1113            distinct: set the DISTINCT flag if and only if this is true.
1114            dialect: the dialect used to parse the input expression.
1115            opts: other options to use to parse the input expressions.
1116
1117        Returns:
1118            The new Except expression.
1119        """
1120        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):
1123class UDTF(DerivedTable):
1124    @property
1125    def selects(self) -> t.List[Expression]:
1126        alias = self.args.get("alias")
1127        return alias.columns if alias else []
selects: List[Expression]
1124    @property
1125    def selects(self) -> t.List[Expression]:
1126        alias = self.args.get("alias")
1127        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1130class Cache(Expression):
1131    arg_types = {
1132        "this": True,
1133        "lazy": False,
1134        "options": False,
1135        "expression": False,
1136    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1139class Uncache(Expression):
1140    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1143class Refresh(Expression):
1144    pass
key = 'refresh'
class DDL(Expression):
1147class DDL(Expression):
1148    @property
1149    def ctes(self) -> t.List[CTE]:
1150        """Returns a list of all the CTEs attached to this statement."""
1151        with_ = self.args.get("with")
1152        return with_.expressions if with_ else []
1153
1154    @property
1155    def selects(self) -> t.List[Expression]:
1156        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1157        return self.expression.selects if isinstance(self.expression, Query) else []
1158
1159    @property
1160    def named_selects(self) -> t.List[str]:
1161        """
1162        If this statement contains a query (e.g. a CTAS), this returns the output
1163        names of the query's projections.
1164        """
1165        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1148    @property
1149    def ctes(self) -> t.List[CTE]:
1150        """Returns a list of all the CTEs attached to this statement."""
1151        with_ = self.args.get("with")
1152        return with_.expressions if with_ else []

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

selects: List[Expression]
1154    @property
1155    def selects(self) -> t.List[Expression]:
1156        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1157        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]
1159    @property
1160    def named_selects(self) -> t.List[str]:
1161        """
1162        If this statement contains a query (e.g. a CTAS), this returns the output
1163        names of the query's projections.
1164        """
1165        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):
1168class DML(Expression):
1169    def returning(
1170        self,
1171        expression: ExpOrStr,
1172        dialect: DialectType = None,
1173        copy: bool = True,
1174        **opts,
1175    ) -> DML:
1176        """
1177        Set the RETURNING expression. Not supported by all dialects.
1178
1179        Example:
1180            >>> delete("tbl").returning("*", dialect="postgres").sql()
1181            'DELETE FROM tbl RETURNING *'
1182
1183        Args:
1184            expression: the SQL code strings to parse.
1185                If an `Expression` instance is passed, it will be used as-is.
1186            dialect: the dialect used to parse the input expressions.
1187            copy: if `False`, modify this expression instance in-place.
1188            opts: other options to use to parse the input expressions.
1189
1190        Returns:
1191            Delete: the modified expression.
1192        """
1193        return _apply_builder(
1194            expression=expression,
1195            instance=self,
1196            arg="returning",
1197            prefix="RETURNING",
1198            dialect=dialect,
1199            copy=copy,
1200            into=Returning,
1201            **opts,
1202        )
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:
1169    def returning(
1170        self,
1171        expression: ExpOrStr,
1172        dialect: DialectType = None,
1173        copy: bool = True,
1174        **opts,
1175    ) -> DML:
1176        """
1177        Set the RETURNING expression. Not supported by all dialects.
1178
1179        Example:
1180            >>> delete("tbl").returning("*", dialect="postgres").sql()
1181            'DELETE FROM tbl RETURNING *'
1182
1183        Args:
1184            expression: the SQL code strings to parse.
1185                If an `Expression` instance is passed, it will be used as-is.
1186            dialect: the dialect used to parse the input expressions.
1187            copy: if `False`, modify this expression instance in-place.
1188            opts: other options to use to parse the input expressions.
1189
1190        Returns:
1191            Delete: the modified expression.
1192        """
1193        return _apply_builder(
1194            expression=expression,
1195            instance=self,
1196            arg="returning",
1197            prefix="RETURNING",
1198            dialect=dialect,
1199            copy=copy,
1200            into=Returning,
1201            **opts,
1202        )

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):
1205class Create(DDL):
1206    arg_types = {
1207        "with": False,
1208        "this": True,
1209        "kind": True,
1210        "expression": False,
1211        "exists": False,
1212        "properties": False,
1213        "replace": False,
1214        "unique": False,
1215        "indexes": False,
1216        "no_schema_binding": False,
1217        "begin": False,
1218        "end": False,
1219        "clone": False,
1220    }
1221
1222    @property
1223    def kind(self) -> t.Optional[str]:
1224        kind = self.args.get("kind")
1225        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]
1222    @property
1223    def kind(self) -> t.Optional[str]:
1224        kind = self.args.get("kind")
1225        return kind and kind.upper()
key = 'create'
class TruncateTable(Expression):
1228class TruncateTable(Expression):
1229    arg_types = {
1230        "expressions": True,
1231        "is_database": False,
1232        "exists": False,
1233        "only": False,
1234        "cluster": False,
1235        "identity": False,
1236        "option": False,
1237        "partition": False,
1238    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1244class Clone(Expression):
1245    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1248class Describe(Expression):
1249    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):
1252class Kill(Expression):
1253    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1256class Pragma(Expression):
1257    pass
key = 'pragma'
class Set(Expression):
1260class Set(Expression):
1261    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1264class Heredoc(Expression):
1265    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1268class SetItem(Expression):
1269    arg_types = {
1270        "this": False,
1271        "expressions": False,
1272        "kind": False,
1273        "collate": False,  # MySQL SET NAMES statement
1274        "global": False,
1275    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1278class Show(Expression):
1279    arg_types = {
1280        "this": True,
1281        "history": False,
1282        "terse": False,
1283        "target": False,
1284        "offset": False,
1285        "starts_with": False,
1286        "limit": False,
1287        "from": False,
1288        "like": False,
1289        "where": False,
1290        "db": False,
1291        "scope": False,
1292        "scope_kind": False,
1293        "full": False,
1294        "mutex": False,
1295        "query": False,
1296        "channel": False,
1297        "global": False,
1298        "log": False,
1299        "position": False,
1300        "types": False,
1301    }
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):
1304class UserDefinedFunction(Expression):
1305    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1308class CharacterSet(Expression):
1309    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1312class With(Expression):
1313    arg_types = {"expressions": True, "recursive": False}
1314
1315    @property
1316    def recursive(self) -> bool:
1317        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1315    @property
1316    def recursive(self) -> bool:
1317        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1320class WithinGroup(Expression):
1321    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1326class CTE(DerivedTable):
1327    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1330class TableAlias(Expression):
1331    arg_types = {"this": False, "columns": False}
1332
1333    @property
1334    def columns(self):
1335        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1333    @property
1334    def columns(self):
1335        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1338class BitString(Condition):
1339    pass
key = 'bitstring'
class HexString(Condition):
1342class HexString(Condition):
1343    pass
key = 'hexstring'
class ByteString(Condition):
1346class ByteString(Condition):
1347    pass
key = 'bytestring'
class RawString(Condition):
1350class RawString(Condition):
1351    pass
key = 'rawstring'
class UnicodeString(Condition):
1354class UnicodeString(Condition):
1355    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1358class Column(Condition):
1359    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1360
1361    @property
1362    def table(self) -> str:
1363        return self.text("table")
1364
1365    @property
1366    def db(self) -> str:
1367        return self.text("db")
1368
1369    @property
1370    def catalog(self) -> str:
1371        return self.text("catalog")
1372
1373    @property
1374    def output_name(self) -> str:
1375        return self.name
1376
1377    @property
1378    def parts(self) -> t.List[Identifier]:
1379        """Return the parts of a column in order catalog, db, table, name."""
1380        return [
1381            t.cast(Identifier, self.args[part])
1382            for part in ("catalog", "db", "table", "this")
1383            if self.args.get(part)
1384        ]
1385
1386    def to_dot(self) -> Dot | Identifier:
1387        """Converts the column into a dot expression."""
1388        parts = self.parts
1389        parent = self.parent
1390
1391        while parent:
1392            if isinstance(parent, Dot):
1393                parts.append(parent.expression)
1394            parent = parent.parent
1395
1396        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
1361    @property
1362    def table(self) -> str:
1363        return self.text("table")
db: str
1365    @property
1366    def db(self) -> str:
1367        return self.text("db")
catalog: str
1369    @property
1370    def catalog(self) -> str:
1371        return self.text("catalog")
output_name: str
1373    @property
1374    def output_name(self) -> str:
1375        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]
1377    @property
1378    def parts(self) -> t.List[Identifier]:
1379        """Return the parts of a column in order catalog, db, table, name."""
1380        return [
1381            t.cast(Identifier, self.args[part])
1382            for part in ("catalog", "db", "table", "this")
1383            if self.args.get(part)
1384        ]

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1399class ColumnPosition(Expression):
1400    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1403class ColumnDef(Expression):
1404    arg_types = {
1405        "this": True,
1406        "kind": False,
1407        "constraints": False,
1408        "exists": False,
1409        "position": False,
1410    }
1411
1412    @property
1413    def constraints(self) -> t.List[ColumnConstraint]:
1414        return self.args.get("constraints") or []
1415
1416    @property
1417    def kind(self) -> t.Optional[DataType]:
1418        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1412    @property
1413    def constraints(self) -> t.List[ColumnConstraint]:
1414        return self.args.get("constraints") or []
kind: Optional[DataType]
1416    @property
1417    def kind(self) -> t.Optional[DataType]:
1418        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1421class AlterColumn(Expression):
1422    arg_types = {
1423        "this": True,
1424        "dtype": False,
1425        "collate": False,
1426        "using": False,
1427        "default": False,
1428        "drop": False,
1429        "comment": False,
1430    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1433class RenameColumn(Expression):
1434    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1437class RenameTable(Expression):
1438    pass
key = 'renametable'
class SwapTable(Expression):
1441class SwapTable(Expression):
1442    pass
key = 'swaptable'
class Comment(Expression):
1445class Comment(Expression):
1446    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):
1449class Comprehension(Expression):
1450    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):
1454class MergeTreeTTLAction(Expression):
1455    arg_types = {
1456        "this": True,
1457        "delete": False,
1458        "recompress": False,
1459        "to_disk": False,
1460        "to_volume": False,
1461    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1465class MergeTreeTTL(Expression):
1466    arg_types = {
1467        "expressions": True,
1468        "where": False,
1469        "group": False,
1470        "aggregates": False,
1471    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1475class IndexConstraintOption(Expression):
1476    arg_types = {
1477        "key_block_size": False,
1478        "using": False,
1479        "parser": False,
1480        "comment": False,
1481        "visible": False,
1482        "engine_attr": False,
1483        "secondary_engine_attr": False,
1484    }
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):
1487class ColumnConstraint(Expression):
1488    arg_types = {"this": False, "kind": True}
1489
1490    @property
1491    def kind(self) -> ColumnConstraintKind:
1492        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1490    @property
1491    def kind(self) -> ColumnConstraintKind:
1492        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1495class ColumnConstraintKind(Expression):
1496    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1499class AutoIncrementColumnConstraint(ColumnConstraintKind):
1500    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1503class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1504    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1507class CaseSpecificColumnConstraint(ColumnConstraintKind):
1508    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1511class CharacterSetColumnConstraint(ColumnConstraintKind):
1512    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1515class CheckColumnConstraint(ColumnConstraintKind):
1516    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1519class ClusteredColumnConstraint(ColumnConstraintKind):
1520    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1523class CollateColumnConstraint(ColumnConstraintKind):
1524    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1527class CommentColumnConstraint(ColumnConstraintKind):
1528    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1531class CompressColumnConstraint(ColumnConstraintKind):
1532    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1535class DateFormatColumnConstraint(ColumnConstraintKind):
1536    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1539class DefaultColumnConstraint(ColumnConstraintKind):
1540    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1543class EncodeColumnConstraint(ColumnConstraintKind):
1544    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1547class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1548    # this: True -> ALWAYS, this: False -> BY DEFAULT
1549    arg_types = {
1550        "this": False,
1551        "expression": False,
1552        "on_null": False,
1553        "start": False,
1554        "increment": False,
1555        "minvalue": False,
1556        "maxvalue": False,
1557        "cycle": False,
1558    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1561class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1562    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1566class IndexColumnConstraint(ColumnConstraintKind):
1567    arg_types = {
1568        "this": False,
1569        "schema": True,
1570        "kind": False,
1571        "index_type": False,
1572        "options": False,
1573    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1576class InlineLengthColumnConstraint(ColumnConstraintKind):
1577    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1580class NonClusteredColumnConstraint(ColumnConstraintKind):
1581    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1584class NotForReplicationColumnConstraint(ColumnConstraintKind):
1585    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1588class NotNullColumnConstraint(ColumnConstraintKind):
1589    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1593class OnUpdateColumnConstraint(ColumnConstraintKind):
1594    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1598class TransformColumnConstraint(ColumnConstraintKind):
1599    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1602class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1603    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1606class TitleColumnConstraint(ColumnConstraintKind):
1607    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1610class UniqueColumnConstraint(ColumnConstraintKind):
1611    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1614class UppercaseColumnConstraint(ColumnConstraintKind):
1615    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1618class PathColumnConstraint(ColumnConstraintKind):
1619    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1624class ComputedColumnConstraint(ColumnConstraintKind):
1625    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1628class Constraint(Expression):
1629    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1632class Delete(DML):
1633    arg_types = {
1634        "with": False,
1635        "this": False,
1636        "using": False,
1637        "where": False,
1638        "returning": False,
1639        "limit": False,
1640        "tables": False,  # Multiple-Table Syntax (MySQL)
1641    }
1642
1643    def delete(
1644        self,
1645        table: ExpOrStr,
1646        dialect: DialectType = None,
1647        copy: bool = True,
1648        **opts,
1649    ) -> Delete:
1650        """
1651        Create a DELETE expression or replace the table on an existing DELETE expression.
1652
1653        Example:
1654            >>> delete("tbl").sql()
1655            'DELETE FROM tbl'
1656
1657        Args:
1658            table: the table from which to delete.
1659            dialect: the dialect used to parse the input expression.
1660            copy: if `False`, modify this expression instance in-place.
1661            opts: other options to use to parse the input expressions.
1662
1663        Returns:
1664            Delete: the modified expression.
1665        """
1666        return _apply_builder(
1667            expression=table,
1668            instance=self,
1669            arg="this",
1670            dialect=dialect,
1671            into=Table,
1672            copy=copy,
1673            **opts,
1674        )
1675
1676    def where(
1677        self,
1678        *expressions: t.Optional[ExpOrStr],
1679        append: bool = True,
1680        dialect: DialectType = None,
1681        copy: bool = True,
1682        **opts,
1683    ) -> Delete:
1684        """
1685        Append to or set the WHERE expressions.
1686
1687        Example:
1688            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1689            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1690
1691        Args:
1692            *expressions: the SQL code strings to parse.
1693                If an `Expression` instance is passed, it will be used as-is.
1694                Multiple expressions are combined with an AND operator.
1695            append: if `True`, AND the new expressions to any existing expression.
1696                Otherwise, this resets the expression.
1697            dialect: the dialect used to parse the input expressions.
1698            copy: if `False`, modify this expression instance in-place.
1699            opts: other options to use to parse the input expressions.
1700
1701        Returns:
1702            Delete: the modified expression.
1703        """
1704        return _apply_conjunction_builder(
1705            *expressions,
1706            instance=self,
1707            arg="where",
1708            append=append,
1709            into=Where,
1710            dialect=dialect,
1711            copy=copy,
1712            **opts,
1713        )
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:
1643    def delete(
1644        self,
1645        table: ExpOrStr,
1646        dialect: DialectType = None,
1647        copy: bool = True,
1648        **opts,
1649    ) -> Delete:
1650        """
1651        Create a DELETE expression or replace the table on an existing DELETE expression.
1652
1653        Example:
1654            >>> delete("tbl").sql()
1655            'DELETE FROM tbl'
1656
1657        Args:
1658            table: the table from which to delete.
1659            dialect: the dialect used to parse the input expression.
1660            copy: if `False`, modify this expression instance in-place.
1661            opts: other options to use to parse the input expressions.
1662
1663        Returns:
1664            Delete: the modified expression.
1665        """
1666        return _apply_builder(
1667            expression=table,
1668            instance=self,
1669            arg="this",
1670            dialect=dialect,
1671            into=Table,
1672            copy=copy,
1673            **opts,
1674        )

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

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):
1716class Drop(Expression):
1717    arg_types = {
1718        "this": False,
1719        "kind": False,
1720        "exists": False,
1721        "temporary": False,
1722        "materialized": False,
1723        "cascade": False,
1724        "constraints": False,
1725        "purge": False,
1726    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1729class Filter(Expression):
1730    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1733class Check(Expression):
1734    pass
key = 'check'
class Connect(Expression):
1738class Connect(Expression):
1739    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1742class Prior(Expression):
1743    pass
key = 'prior'
class Directory(Expression):
1746class Directory(Expression):
1747    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1748    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1751class ForeignKey(Expression):
1752    arg_types = {
1753        "expressions": True,
1754        "reference": False,
1755        "delete": False,
1756        "update": False,
1757    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1760class ColumnPrefix(Expression):
1761    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1764class PrimaryKey(Expression):
1765    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1770class Into(Expression):
1771    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1774class From(Expression):
1775    @property
1776    def name(self) -> str:
1777        return self.this.name
1778
1779    @property
1780    def alias_or_name(self) -> str:
1781        return self.this.alias_or_name
name: str
1775    @property
1776    def name(self) -> str:
1777        return self.this.name
alias_or_name: str
1779    @property
1780    def alias_or_name(self) -> str:
1781        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1784class Having(Expression):
1785    pass
key = 'having'
class Hint(Expression):
1788class Hint(Expression):
1789    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1792class JoinHint(Expression):
1793    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1796class Identifier(Expression):
1797    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1798
1799    @property
1800    def quoted(self) -> bool:
1801        return bool(self.args.get("quoted"))
1802
1803    @property
1804    def hashable_args(self) -> t.Any:
1805        return (self.this, self.quoted)
1806
1807    @property
1808    def output_name(self) -> str:
1809        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1799    @property
1800    def quoted(self) -> bool:
1801        return bool(self.args.get("quoted"))
hashable_args: Any
1803    @property
1804    def hashable_args(self) -> t.Any:
1805        return (self.this, self.quoted)
output_name: str
1807    @property
1808    def output_name(self) -> str:
1809        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):
1813class Opclass(Expression):
1814    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1817class Index(Expression):
1818    arg_types = {
1819        "this": False,
1820        "table": False,
1821        "using": False,
1822        "where": False,
1823        "columns": False,
1824        "unique": False,
1825        "primary": False,
1826        "amp": False,  # teradata
1827        "include": False,
1828        "partition_by": False,  # teradata
1829    }
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):
1832class Insert(DDL, DML):
1833    arg_types = {
1834        "with": False,
1835        "this": True,
1836        "expression": False,
1837        "conflict": False,
1838        "returning": False,
1839        "overwrite": False,
1840        "exists": False,
1841        "partition": False,
1842        "alternative": False,
1843        "where": False,
1844        "ignore": False,
1845        "by_name": False,
1846    }
1847
1848    def with_(
1849        self,
1850        alias: ExpOrStr,
1851        as_: ExpOrStr,
1852        recursive: t.Optional[bool] = None,
1853        append: bool = True,
1854        dialect: DialectType = None,
1855        copy: bool = True,
1856        **opts,
1857    ) -> Insert:
1858        """
1859        Append to or set the common table expressions.
1860
1861        Example:
1862            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1863            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1864
1865        Args:
1866            alias: the SQL code string to parse as the table name.
1867                If an `Expression` instance is passed, this is used as-is.
1868            as_: the SQL code string to parse as the table expression.
1869                If an `Expression` instance is passed, it will be used as-is.
1870            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1871            append: if `True`, add to any existing expressions.
1872                Otherwise, this resets the expressions.
1873            dialect: the dialect used to parse the input expression.
1874            copy: if `False`, modify this expression instance in-place.
1875            opts: other options to use to parse the input expressions.
1876
1877        Returns:
1878            The modified expression.
1879        """
1880        return _apply_cte_builder(
1881            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1882        )
arg_types = {'with': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1848    def with_(
1849        self,
1850        alias: ExpOrStr,
1851        as_: ExpOrStr,
1852        recursive: t.Optional[bool] = None,
1853        append: bool = True,
1854        dialect: DialectType = None,
1855        copy: bool = True,
1856        **opts,
1857    ) -> Insert:
1858        """
1859        Append to or set the common table expressions.
1860
1861        Example:
1862            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1863            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1864
1865        Args:
1866            alias: the SQL code string to parse as the table name.
1867                If an `Expression` instance is passed, this is used as-is.
1868            as_: the SQL code string to parse as the table expression.
1869                If an `Expression` instance is passed, it will be used as-is.
1870            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1871            append: if `True`, add to any existing expressions.
1872                Otherwise, this resets the expressions.
1873            dialect: the dialect used to parse the input expression.
1874            copy: if `False`, modify this expression instance in-place.
1875            opts: other options to use to parse the input expressions.
1876
1877        Returns:
1878            The modified expression.
1879        """
1880        return _apply_cte_builder(
1881            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1882        )

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

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2706    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2707        parts = self.parts
2708        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2709        alias = self.args.get("alias")
2710        if alias:
2711            col = alias_(col, alias.this, copy=copy)
2712        return col
key = 'table'
class Union(Query):
2715class Union(Query):
2716    arg_types = {
2717        "with": False,
2718        "this": True,
2719        "expression": True,
2720        "distinct": False,
2721        "by_name": False,
2722        **QUERY_MODIFIERS,
2723    }
2724
2725    def select(
2726        self,
2727        *expressions: t.Optional[ExpOrStr],
2728        append: bool = True,
2729        dialect: DialectType = None,
2730        copy: bool = True,
2731        **opts,
2732    ) -> Union:
2733        this = maybe_copy(self, copy)
2734        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2735        this.expression.unnest().select(
2736            *expressions, append=append, dialect=dialect, copy=False, **opts
2737        )
2738        return this
2739
2740    @property
2741    def named_selects(self) -> t.List[str]:
2742        return self.this.unnest().named_selects
2743
2744    @property
2745    def is_star(self) -> bool:
2746        return self.this.is_star or self.expression.is_star
2747
2748    @property
2749    def selects(self) -> t.List[Expression]:
2750        return self.this.unnest().selects
2751
2752    @property
2753    def left(self) -> Expression:
2754        return self.this
2755
2756    @property
2757    def right(self) -> Expression:
2758        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:
2725    def select(
2726        self,
2727        *expressions: t.Optional[ExpOrStr],
2728        append: bool = True,
2729        dialect: DialectType = None,
2730        copy: bool = True,
2731        **opts,
2732    ) -> Union:
2733        this = maybe_copy(self, copy)
2734        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2735        this.expression.unnest().select(
2736            *expressions, append=append, dialect=dialect, copy=False, **opts
2737        )
2738        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]
2740    @property
2741    def named_selects(self) -> t.List[str]:
2742        return self.this.unnest().named_selects

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

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

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:
2918    def order_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 ORDER BY expression.
2928
2929        Example:
2930            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2931            'SELECT x FROM tbl ORDER BY x DESC'
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 `Order`.
2937            append: if `True`, add to any existing expressions.
2938                Otherwise, this flattens all the `Order` 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        return _apply_child_list_builder(
2947            *expressions,
2948            instance=self,
2949            arg="order",
2950            append=append,
2951            copy=copy,
2952            prefix="ORDER BY",
2953            into=Order,
2954            dialect=dialect,
2955            **opts,
2956        )

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3500    def unwrap(self) -> Subquery:
3501        expression = self
3502        while expression.same_parent and expression.is_wrapper:
3503            expression = t.cast(Subquery, expression.parent)
3504        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:
3506    def select(
3507        self,
3508        *expressions: t.Optional[ExpOrStr],
3509        append: bool = True,
3510        dialect: DialectType = None,
3511        copy: bool = True,
3512        **opts,
3513    ) -> Subquery:
3514        this = maybe_copy(self, copy)
3515        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3516        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
3518    @property
3519    def is_wrapper(self) -> bool:
3520        """
3521        Whether this Subquery acts as a simple wrapper around another expression.
3522
3523        SELECT * FROM (((SELECT * FROM t)))
3524                      ^
3525                      This corresponds to a "wrapper" Subquery node
3526        """
3527        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
3529    @property
3530    def is_star(self) -> bool:
3531        return self.this.is_star

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3565class Pivot(Expression):
3566    arg_types = {
3567        "this": False,
3568        "alias": False,
3569        "expressions": False,
3570        "field": False,
3571        "unpivot": False,
3572        "using": False,
3573        "group": False,
3574        "columns": False,
3575        "include_nulls": False,
3576    }
3577
3578    @property
3579    def unpivot(self) -> bool:
3580        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
3578    @property
3579    def unpivot(self) -> bool:
3580        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3583class Window(Condition):
3584    arg_types = {
3585        "this": True,
3586        "partition_by": False,
3587        "order": False,
3588        "spec": False,
3589        "alias": False,
3590        "over": False,
3591        "first": False,
3592    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3595class WindowSpec(Expression):
3596    arg_types = {
3597        "kind": False,
3598        "start": False,
3599        "start_side": False,
3600        "end": False,
3601        "end_side": False,
3602    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3605class PreWhere(Expression):
3606    pass
key = 'prewhere'
class Where(Expression):
3609class Where(Expression):
3610    pass
key = 'where'
class Star(Expression):
3613class Star(Expression):
3614    arg_types = {"except": False, "replace": False}
3615
3616    @property
3617    def name(self) -> str:
3618        return "*"
3619
3620    @property
3621    def output_name(self) -> str:
3622        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3616    @property
3617    def name(self) -> str:
3618        return "*"
output_name: str
3620    @property
3621    def output_name(self) -> str:
3622        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):
3625class Parameter(Condition):
3626    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3629class SessionParameter(Condition):
3630    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3633class Placeholder(Condition):
3634    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3637class Null(Condition):
3638    arg_types: t.Dict[str, t.Any] = {}
3639
3640    @property
3641    def name(self) -> str:
3642        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3640    @property
3641    def name(self) -> str:
3642        return "NULL"
key = 'null'
class Boolean(Condition):
3645class Boolean(Condition):
3646    pass
key = 'boolean'
class DataTypeParam(Expression):
3649class DataTypeParam(Expression):
3650    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3653class DataType(Expression):
3654    arg_types = {
3655        "this": True,
3656        "expressions": False,
3657        "nested": False,
3658        "values": False,
3659        "prefix": False,
3660        "kind": False,
3661    }
3662
3663    class Type(AutoName):
3664        ARRAY = auto()
3665        AGGREGATEFUNCTION = auto()
3666        SIMPLEAGGREGATEFUNCTION = auto()
3667        BIGDECIMAL = auto()
3668        BIGINT = auto()
3669        BIGSERIAL = auto()
3670        BINARY = auto()
3671        BIT = auto()
3672        BOOLEAN = auto()
3673        BPCHAR = auto()
3674        CHAR = auto()
3675        DATE = auto()
3676        DATE32 = auto()
3677        DATEMULTIRANGE = auto()
3678        DATERANGE = auto()
3679        DATETIME = auto()
3680        DATETIME64 = auto()
3681        DECIMAL = auto()
3682        DOUBLE = auto()
3683        ENUM = auto()
3684        ENUM8 = auto()
3685        ENUM16 = auto()
3686        FIXEDSTRING = auto()
3687        FLOAT = auto()
3688        GEOGRAPHY = auto()
3689        GEOMETRY = auto()
3690        HLLSKETCH = auto()
3691        HSTORE = auto()
3692        IMAGE = auto()
3693        INET = auto()
3694        INT = auto()
3695        INT128 = auto()
3696        INT256 = auto()
3697        INT4MULTIRANGE = auto()
3698        INT4RANGE = auto()
3699        INT8MULTIRANGE = auto()
3700        INT8RANGE = auto()
3701        INTERVAL = auto()
3702        IPADDRESS = auto()
3703        IPPREFIX = auto()
3704        IPV4 = auto()
3705        IPV6 = auto()
3706        JSON = auto()
3707        JSONB = auto()
3708        LONGBLOB = auto()
3709        LONGTEXT = auto()
3710        LOWCARDINALITY = auto()
3711        MAP = auto()
3712        MEDIUMBLOB = auto()
3713        MEDIUMINT = auto()
3714        MEDIUMTEXT = auto()
3715        MONEY = auto()
3716        NCHAR = auto()
3717        NESTED = auto()
3718        NULL = auto()
3719        NULLABLE = auto()
3720        NUMMULTIRANGE = auto()
3721        NUMRANGE = auto()
3722        NVARCHAR = auto()
3723        OBJECT = auto()
3724        ROWVERSION = auto()
3725        SERIAL = auto()
3726        SET = auto()
3727        SMALLINT = auto()
3728        SMALLMONEY = auto()
3729        SMALLSERIAL = auto()
3730        STRUCT = auto()
3731        SUPER = auto()
3732        TEXT = auto()
3733        TINYBLOB = auto()
3734        TINYTEXT = auto()
3735        TIME = auto()
3736        TIMETZ = auto()
3737        TIMESTAMP = auto()
3738        TIMESTAMPLTZ = auto()
3739        TIMESTAMPTZ = auto()
3740        TIMESTAMP_S = auto()
3741        TIMESTAMP_MS = auto()
3742        TIMESTAMP_NS = auto()
3743        TINYINT = auto()
3744        TSMULTIRANGE = auto()
3745        TSRANGE = auto()
3746        TSTZMULTIRANGE = auto()
3747        TSTZRANGE = auto()
3748        UBIGINT = auto()
3749        UINT = auto()
3750        UINT128 = auto()
3751        UINT256 = auto()
3752        UMEDIUMINT = auto()
3753        UDECIMAL = auto()
3754        UNIQUEIDENTIFIER = auto()
3755        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3756        USERDEFINED = "USER-DEFINED"
3757        USMALLINT = auto()
3758        UTINYINT = auto()
3759        UUID = auto()
3760        VARBINARY = auto()
3761        VARCHAR = auto()
3762        VARIANT = auto()
3763        XML = auto()
3764        YEAR = auto()
3765
3766    TEXT_TYPES = {
3767        Type.CHAR,
3768        Type.NCHAR,
3769        Type.VARCHAR,
3770        Type.NVARCHAR,
3771        Type.TEXT,
3772    }
3773
3774    INTEGER_TYPES = {
3775        Type.INT,
3776        Type.TINYINT,
3777        Type.SMALLINT,
3778        Type.BIGINT,
3779        Type.INT128,
3780        Type.INT256,
3781        Type.BIT,
3782    }
3783
3784    FLOAT_TYPES = {
3785        Type.FLOAT,
3786        Type.DOUBLE,
3787    }
3788
3789    NUMERIC_TYPES = {
3790        *INTEGER_TYPES,
3791        *FLOAT_TYPES,
3792    }
3793
3794    TEMPORAL_TYPES = {
3795        Type.TIME,
3796        Type.TIMETZ,
3797        Type.TIMESTAMP,
3798        Type.TIMESTAMPTZ,
3799        Type.TIMESTAMPLTZ,
3800        Type.TIMESTAMP_S,
3801        Type.TIMESTAMP_MS,
3802        Type.TIMESTAMP_NS,
3803        Type.DATE,
3804        Type.DATE32,
3805        Type.DATETIME,
3806        Type.DATETIME64,
3807    }
3808
3809    @classmethod
3810    def build(
3811        cls,
3812        dtype: DATA_TYPE,
3813        dialect: DialectType = None,
3814        udt: bool = False,
3815        copy: bool = True,
3816        **kwargs,
3817    ) -> DataType:
3818        """
3819        Constructs a DataType object.
3820
3821        Args:
3822            dtype: the data type of interest.
3823            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3824            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3825                DataType, thus creating a user-defined type.
3826            copy: whether to copy the data type.
3827            kwargs: additional arguments to pass in the constructor of DataType.
3828
3829        Returns:
3830            The constructed DataType object.
3831        """
3832        from sqlglot import parse_one
3833
3834        if isinstance(dtype, str):
3835            if dtype.upper() == "UNKNOWN":
3836                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3837
3838            try:
3839                data_type_exp = parse_one(
3840                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3841                )
3842            except ParseError:
3843                if udt:
3844                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3845                raise
3846        elif isinstance(dtype, DataType.Type):
3847            data_type_exp = DataType(this=dtype)
3848        elif isinstance(dtype, DataType):
3849            return maybe_copy(dtype, copy)
3850        else:
3851            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3852
3853        return DataType(**{**data_type_exp.args, **kwargs})
3854
3855    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3856        """
3857        Checks whether this DataType matches one of the provided data types. Nested types or precision
3858        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3859
3860        Args:
3861            dtypes: the data types to compare this DataType to.
3862
3863        Returns:
3864            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3865        """
3866        for dtype in dtypes:
3867            other = DataType.build(dtype, copy=False, udt=True)
3868
3869            if (
3870                other.expressions
3871                or self.this == DataType.Type.USERDEFINED
3872                or other.this == DataType.Type.USERDEFINED
3873            ):
3874                matches = self == other
3875            else:
3876                matches = self.this == other.this
3877
3878            if matches:
3879                return True
3880        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATE32: 'DATE32'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
3809    @classmethod
3810    def build(
3811        cls,
3812        dtype: DATA_TYPE,
3813        dialect: DialectType = None,
3814        udt: bool = False,
3815        copy: bool = True,
3816        **kwargs,
3817    ) -> DataType:
3818        """
3819        Constructs a DataType object.
3820
3821        Args:
3822            dtype: the data type of interest.
3823            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3824            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3825                DataType, thus creating a user-defined type.
3826            copy: whether to copy the data type.
3827            kwargs: additional arguments to pass in the constructor of DataType.
3828
3829        Returns:
3830            The constructed DataType object.
3831        """
3832        from sqlglot import parse_one
3833
3834        if isinstance(dtype, str):
3835            if dtype.upper() == "UNKNOWN":
3836                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3837
3838            try:
3839                data_type_exp = parse_one(
3840                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3841                )
3842            except ParseError:
3843                if udt:
3844                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3845                raise
3846        elif isinstance(dtype, DataType.Type):
3847            data_type_exp = DataType(this=dtype)
3848        elif isinstance(dtype, DataType):
3849            return maybe_copy(dtype, copy)
3850        else:
3851            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3852
3853        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:
3855    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3856        """
3857        Checks whether this DataType matches one of the provided data types. Nested types or precision
3858        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3859
3860        Args:
3861            dtypes: the data types to compare this DataType to.
3862
3863        Returns:
3864            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3865        """
3866        for dtype in dtypes:
3867            other = DataType.build(dtype, copy=False, udt=True)
3868
3869            if (
3870                other.expressions
3871                or self.this == DataType.Type.USERDEFINED
3872                or other.this == DataType.Type.USERDEFINED
3873            ):
3874                matches = self == other
3875            else:
3876                matches = self.this == other.this
3877
3878            if matches:
3879                return True
3880        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):
3663    class Type(AutoName):
3664        ARRAY = auto()
3665        AGGREGATEFUNCTION = auto()
3666        SIMPLEAGGREGATEFUNCTION = auto()
3667        BIGDECIMAL = auto()
3668        BIGINT = auto()
3669        BIGSERIAL = auto()
3670        BINARY = auto()
3671        BIT = auto()
3672        BOOLEAN = auto()
3673        BPCHAR = auto()
3674        CHAR = auto()
3675        DATE = auto()
3676        DATE32 = auto()
3677        DATEMULTIRANGE = auto()
3678        DATERANGE = auto()
3679        DATETIME = auto()
3680        DATETIME64 = auto()
3681        DECIMAL = auto()
3682        DOUBLE = auto()
3683        ENUM = auto()
3684        ENUM8 = auto()
3685        ENUM16 = auto()
3686        FIXEDSTRING = auto()
3687        FLOAT = auto()
3688        GEOGRAPHY = auto()
3689        GEOMETRY = auto()
3690        HLLSKETCH = auto()
3691        HSTORE = auto()
3692        IMAGE = auto()
3693        INET = auto()
3694        INT = auto()
3695        INT128 = auto()
3696        INT256 = auto()
3697        INT4MULTIRANGE = auto()
3698        INT4RANGE = auto()
3699        INT8MULTIRANGE = auto()
3700        INT8RANGE = auto()
3701        INTERVAL = auto()
3702        IPADDRESS = auto()
3703        IPPREFIX = auto()
3704        IPV4 = auto()
3705        IPV6 = auto()
3706        JSON = auto()
3707        JSONB = auto()
3708        LONGBLOB = auto()
3709        LONGTEXT = auto()
3710        LOWCARDINALITY = auto()
3711        MAP = auto()
3712        MEDIUMBLOB = auto()
3713        MEDIUMINT = auto()
3714        MEDIUMTEXT = auto()
3715        MONEY = auto()
3716        NCHAR = auto()
3717        NESTED = auto()
3718        NULL = auto()
3719        NULLABLE = auto()
3720        NUMMULTIRANGE = auto()
3721        NUMRANGE = auto()
3722        NVARCHAR = auto()
3723        OBJECT = auto()
3724        ROWVERSION = auto()
3725        SERIAL = auto()
3726        SET = auto()
3727        SMALLINT = auto()
3728        SMALLMONEY = auto()
3729        SMALLSERIAL = auto()
3730        STRUCT = auto()
3731        SUPER = auto()
3732        TEXT = auto()
3733        TINYBLOB = auto()
3734        TINYTEXT = auto()
3735        TIME = auto()
3736        TIMETZ = auto()
3737        TIMESTAMP = auto()
3738        TIMESTAMPLTZ = auto()
3739        TIMESTAMPTZ = auto()
3740        TIMESTAMP_S = auto()
3741        TIMESTAMP_MS = auto()
3742        TIMESTAMP_NS = auto()
3743        TINYINT = auto()
3744        TSMULTIRANGE = auto()
3745        TSRANGE = auto()
3746        TSTZMULTIRANGE = auto()
3747        TSTZRANGE = auto()
3748        UBIGINT = auto()
3749        UINT = auto()
3750        UINT128 = auto()
3751        UINT256 = auto()
3752        UMEDIUMINT = auto()
3753        UDECIMAL = auto()
3754        UNIQUEIDENTIFIER = auto()
3755        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3756        USERDEFINED = "USER-DEFINED"
3757        USMALLINT = auto()
3758        UTINYINT = auto()
3759        UUID = auto()
3760        VARBINARY = auto()
3761        VARCHAR = auto()
3762        VARIANT = auto()
3763        XML = auto()
3764        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):
3887class PseudoType(DataType):
3888    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3892class ObjectIdentifier(DataType):
3893    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3897class SubqueryPredicate(Predicate):
3898    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3901class All(SubqueryPredicate):
3902    pass
key = 'all'
class Any(SubqueryPredicate):
3905class Any(SubqueryPredicate):
3906    pass
key = 'any'
class Exists(SubqueryPredicate):
3909class Exists(SubqueryPredicate):
3910    pass
key = 'exists'
class Command(Expression):
3915class Command(Expression):
3916    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3919class Transaction(Expression):
3920    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3923class Commit(Expression):
3924    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3927class Rollback(Expression):
3928    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3931class AlterTable(Expression):
3932    arg_types = {
3933        "this": True,
3934        "actions": True,
3935        "exists": False,
3936        "only": False,
3937        "options": False,
3938    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
3941class AddConstraint(Expression):
3942    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
3945class DropPartition(Expression):
3946    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3950class Binary(Condition):
3951    arg_types = {"this": True, "expression": True}
3952
3953    @property
3954    def left(self) -> Expression:
3955        return self.this
3956
3957    @property
3958    def right(self) -> Expression:
3959        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3953    @property
3954    def left(self) -> Expression:
3955        return self.this
right: Expression
3957    @property
3958    def right(self) -> Expression:
3959        return self.expression
key = 'binary'
class Add(Binary):
3962class Add(Binary):
3963    pass
key = 'add'
class Connector(Binary):
3966class Connector(Binary):
3967    pass
key = 'connector'
class And(Connector):
3970class And(Connector):
3971    pass
key = 'and'
class Or(Connector):
3974class Or(Connector):
3975    pass
key = 'or'
class BitwiseAnd(Binary):
3978class BitwiseAnd(Binary):
3979    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3982class BitwiseLeftShift(Binary):
3983    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3986class BitwiseOr(Binary):
3987    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3990class BitwiseRightShift(Binary):
3991    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3994class BitwiseXor(Binary):
3995    pass
key = 'bitwisexor'
class Div(Binary):
3998class Div(Binary):
3999    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):
4002class Overlaps(Binary):
4003    pass
key = 'overlaps'
class Dot(Binary):
4006class Dot(Binary):
4007    @property
4008    def name(self) -> str:
4009        return self.expression.name
4010
4011    @property
4012    def output_name(self) -> str:
4013        return self.name
4014
4015    @classmethod
4016    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4017        """Build a Dot object with a sequence of expressions."""
4018        if len(expressions) < 2:
4019            raise ValueError("Dot requires >= 2 expressions.")
4020
4021        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4022
4023    @property
4024    def parts(self) -> t.List[Expression]:
4025        """Return the parts of a table / column in order catalog, db, table."""
4026        this, *parts = self.flatten()
4027
4028        parts.reverse()
4029
4030        for arg in ("this", "table", "db", "catalog"):
4031            part = this.args.get(arg)
4032
4033            if isinstance(part, Expression):
4034                parts.append(part)
4035
4036        parts.reverse()
4037        return parts
name: str
4007    @property
4008    def name(self) -> str:
4009        return self.expression.name
output_name: str
4011    @property
4012    def output_name(self) -> str:
4013        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:
4015    @classmethod
4016    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4017        """Build a Dot object with a sequence of expressions."""
4018        if len(expressions) < 2:
4019            raise ValueError("Dot requires >= 2 expressions.")
4020
4021        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]
4023    @property
4024    def parts(self) -> t.List[Expression]:
4025        """Return the parts of a table / column in order catalog, db, table."""
4026        this, *parts = self.flatten()
4027
4028        parts.reverse()
4029
4030        for arg in ("this", "table", "db", "catalog"):
4031            part = this.args.get(arg)
4032
4033            if isinstance(part, Expression):
4034                parts.append(part)
4035
4036        parts.reverse()
4037        return parts

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

key = 'dot'
class DPipe(Binary):
4040class DPipe(Binary):
4041    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4044class EQ(Binary, Predicate):
4045    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4048class NullSafeEQ(Binary, Predicate):
4049    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4052class NullSafeNEQ(Binary, Predicate):
4053    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4057class PropertyEQ(Binary):
4058    pass
key = 'propertyeq'
class Distance(Binary):
4061class Distance(Binary):
4062    pass
key = 'distance'
class Escape(Binary):
4065class Escape(Binary):
4066    pass
key = 'escape'
class Glob(Binary, Predicate):
4069class Glob(Binary, Predicate):
4070    pass
key = 'glob'
class GT(Binary, Predicate):
4073class GT(Binary, Predicate):
4074    pass
key = 'gt'
class GTE(Binary, Predicate):
4077class GTE(Binary, Predicate):
4078    pass
key = 'gte'
class ILike(Binary, Predicate):
4081class ILike(Binary, Predicate):
4082    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4085class ILikeAny(Binary, Predicate):
4086    pass
key = 'ilikeany'
class IntDiv(Binary):
4089class IntDiv(Binary):
4090    pass
key = 'intdiv'
class Is(Binary, Predicate):
4093class Is(Binary, Predicate):
4094    pass
key = 'is'
class Kwarg(Binary):
4097class Kwarg(Binary):
4098    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4101class Like(Binary, Predicate):
4102    pass
key = 'like'
class LikeAny(Binary, Predicate):
4105class LikeAny(Binary, Predicate):
4106    pass
key = 'likeany'
class LT(Binary, Predicate):
4109class LT(Binary, Predicate):
4110    pass
key = 'lt'
class LTE(Binary, Predicate):
4113class LTE(Binary, Predicate):
4114    pass
key = 'lte'
class Mod(Binary):
4117class Mod(Binary):
4118    pass
key = 'mod'
class Mul(Binary):
4121class Mul(Binary):
4122    pass
key = 'mul'
class NEQ(Binary, Predicate):
4125class NEQ(Binary, Predicate):
4126    pass
key = 'neq'
class Operator(Binary):
4130class Operator(Binary):
4131    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4134class SimilarTo(Binary, Predicate):
4135    pass
key = 'similarto'
class Slice(Binary):
4138class Slice(Binary):
4139    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4142class Sub(Binary):
4143    pass
key = 'sub'
class Unary(Condition):
4148class Unary(Condition):
4149    pass
key = 'unary'
class BitwiseNot(Unary):
4152class BitwiseNot(Unary):
4153    pass
key = 'bitwisenot'
class Not(Unary):
4156class Not(Unary):
4157    pass
key = 'not'
class Paren(Unary):
4160class Paren(Unary):
4161    arg_types = {"this": True, "with": False}
4162
4163    @property
4164    def output_name(self) -> str:
4165        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4163    @property
4164    def output_name(self) -> str:
4165        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):
4168class Neg(Unary):
4169    pass
key = 'neg'
class Alias(Expression):
4172class Alias(Expression):
4173    arg_types = {"this": True, "alias": False}
4174
4175    @property
4176    def output_name(self) -> str:
4177        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4175    @property
4176    def output_name(self) -> str:
4177        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):
4182class PivotAlias(Alias):
4183    pass
key = 'pivotalias'
class Aliases(Expression):
4186class Aliases(Expression):
4187    arg_types = {"this": True, "expressions": True}
4188
4189    @property
4190    def aliases(self):
4191        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4189    @property
4190    def aliases(self):
4191        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4195class AtIndex(Expression):
4196    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4199class AtTimeZone(Expression):
4200    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4203class FromTimeZone(Expression):
4204    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4207class Between(Predicate):
4208    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4211class Bracket(Condition):
4212    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4213    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4214
4215    @property
4216    def output_name(self) -> str:
4217        if len(self.expressions) == 1:
4218            return self.expressions[0].output_name
4219
4220        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4215    @property
4216    def output_name(self) -> str:
4217        if len(self.expressions) == 1:
4218            return self.expressions[0].output_name
4219
4220        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):
4223class Distinct(Expression):
4224    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4227class In(Predicate):
4228    arg_types = {
4229        "this": True,
4230        "expressions": False,
4231        "query": False,
4232        "unnest": False,
4233        "field": False,
4234        "is_global": False,
4235    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4239class ForIn(Expression):
4240    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4243class TimeUnit(Expression):
4244    """Automatically converts unit arg into a var."""
4245
4246    arg_types = {"unit": False}
4247
4248    UNABBREVIATED_UNIT_NAME = {
4249        "D": "DAY",
4250        "H": "HOUR",
4251        "M": "MINUTE",
4252        "MS": "MILLISECOND",
4253        "NS": "NANOSECOND",
4254        "Q": "QUARTER",
4255        "S": "SECOND",
4256        "US": "MICROSECOND",
4257        "W": "WEEK",
4258        "Y": "YEAR",
4259    }
4260
4261    VAR_LIKE = (Column, Literal, Var)
4262
4263    def __init__(self, **args):
4264        unit = args.get("unit")
4265        if isinstance(unit, self.VAR_LIKE):
4266            args["unit"] = Var(
4267                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4268            )
4269        elif isinstance(unit, Week):
4270            unit.set("this", Var(this=unit.this.name.upper()))
4271
4272        super().__init__(**args)
4273
4274    @property
4275    def unit(self) -> t.Optional[Var]:
4276        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4263    def __init__(self, **args):
4264        unit = args.get("unit")
4265        if isinstance(unit, self.VAR_LIKE):
4266            args["unit"] = Var(
4267                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4268            )
4269        elif isinstance(unit, Week):
4270            unit.set("this", Var(this=unit.this.name.upper()))
4271
4272        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]
4274    @property
4275    def unit(self) -> t.Optional[Var]:
4276        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4279class IntervalOp(TimeUnit):
4280    arg_types = {"unit": True, "expression": True}
4281
4282    def interval(self):
4283        return Interval(
4284            this=self.expression.copy(),
4285            unit=self.unit.copy(),
4286        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4282    def interval(self):
4283        return Interval(
4284            this=self.expression.copy(),
4285            unit=self.unit.copy(),
4286        )
key = 'intervalop'
class IntervalSpan(DataType):
4292class IntervalSpan(DataType):
4293    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4296class Interval(TimeUnit):
4297    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4300class IgnoreNulls(Expression):
4301    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4304class RespectNulls(Expression):
4305    pass
key = 'respectnulls'
class HavingMax(Expression):
4309class HavingMax(Expression):
4310    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4314class Func(Condition):
4315    """
4316    The base class for all function expressions.
4317
4318    Attributes:
4319        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4320            treated as a variable length argument and the argument's value will be stored as a list.
4321        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4322            function expression. These values are used to map this node to a name during parsing as
4323            well as to provide the function's name during SQL string generation. By default the SQL
4324            name is set to the expression's class name transformed to snake case.
4325    """
4326
4327    is_var_len_args = False
4328
4329    @classmethod
4330    def from_arg_list(cls, args):
4331        if cls.is_var_len_args:
4332            all_arg_keys = list(cls.arg_types)
4333            # If this function supports variable length argument treat the last argument as such.
4334            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4335            num_non_var = len(non_var_len_arg_keys)
4336
4337            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4338            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4339        else:
4340            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4341
4342        return cls(**args_dict)
4343
4344    @classmethod
4345    def sql_names(cls):
4346        if cls is Func:
4347            raise NotImplementedError(
4348                "SQL name is only supported by concrete function implementations"
4349            )
4350        if "_sql_names" not in cls.__dict__:
4351            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4352        return cls._sql_names
4353
4354    @classmethod
4355    def sql_name(cls):
4356        return cls.sql_names()[0]
4357
4358    @classmethod
4359    def default_parser_mappings(cls):
4360        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):
4329    @classmethod
4330    def from_arg_list(cls, args):
4331        if cls.is_var_len_args:
4332            all_arg_keys = list(cls.arg_types)
4333            # If this function supports variable length argument treat the last argument as such.
4334            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4335            num_non_var = len(non_var_len_arg_keys)
4336
4337            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4338            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4339        else:
4340            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4341
4342        return cls(**args_dict)
@classmethod
def sql_names(cls):
4344    @classmethod
4345    def sql_names(cls):
4346        if cls is Func:
4347            raise NotImplementedError(
4348                "SQL name is only supported by concrete function implementations"
4349            )
4350        if "_sql_names" not in cls.__dict__:
4351            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4352        return cls._sql_names
@classmethod
def sql_name(cls):
4354    @classmethod
4355    def sql_name(cls):
4356        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4358    @classmethod
4359    def default_parser_mappings(cls):
4360        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4363class AggFunc(Func):
4364    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4367class ParameterizedAgg(AggFunc):
4368    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4371class Abs(Func):
4372    pass
key = 'abs'
class ArgMax(AggFunc):
4375class ArgMax(AggFunc):
4376    arg_types = {"this": True, "expression": True, "count": False}
4377    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4380class ArgMin(AggFunc):
4381    arg_types = {"this": True, "expression": True, "count": False}
4382    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4385class ApproxTopK(AggFunc):
4386    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4389class Flatten(Func):
4390    pass
key = 'flatten'
class Transform(Func):
4394class Transform(Func):
4395    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4398class Anonymous(Func):
4399    arg_types = {"this": True, "expressions": False}
4400    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4403class AnonymousAggFunc(AggFunc):
4404    arg_types = {"this": True, "expressions": False}
4405    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4409class CombinedAggFunc(AnonymousAggFunc):
4410    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4413class CombinedParameterizedAgg(ParameterizedAgg):
4414    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):
4419class Hll(AggFunc):
4420    arg_types = {"this": True, "expressions": False}
4421    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4424class ApproxDistinct(AggFunc):
4425    arg_types = {"this": True, "accuracy": False}
4426    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4429class Array(Func):
4430    arg_types = {"expressions": False}
4431    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4435class ToArray(Func):
4436    pass
key = 'toarray'
class ToChar(Func):
4441class ToChar(Func):
4442    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4445class GenerateSeries(Func):
4446    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):
4449class ArrayAgg(AggFunc):
4450    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4453class ArrayUniqueAgg(AggFunc):
4454    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4457class ArrayAll(Func):
4458    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4462class ArrayAny(Func):
4463    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4466class ArrayConcat(Func):
4467    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4468    arg_types = {"this": True, "expressions": False}
4469    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4472class ArrayContains(Binary, Func):
4473    pass
key = 'arraycontains'
class ArrayContained(Binary):
4476class ArrayContained(Binary):
4477    pass
key = 'arraycontained'
class ArrayFilter(Func):
4480class ArrayFilter(Func):
4481    arg_types = {"this": True, "expression": True}
4482    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4485class ArrayJoin(Func):
4486    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4489class ArrayOverlaps(Binary, Func):
4490    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4493class ArraySize(Func):
4494    arg_types = {"this": True, "expression": False}
4495    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4498class ArraySort(Func):
4499    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4502class ArraySum(Func):
4503    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4506class ArrayUnionAgg(AggFunc):
4507    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4510class Avg(AggFunc):
4511    pass
key = 'avg'
class AnyValue(AggFunc):
4514class AnyValue(AggFunc):
4515    pass
key = 'anyvalue'
class Lag(AggFunc):
4518class Lag(AggFunc):
4519    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4522class Lead(AggFunc):
4523    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4528class First(AggFunc):
4529    pass
key = 'first'
class Last(AggFunc):
4532class Last(AggFunc):
4533    pass
key = 'last'
class FirstValue(AggFunc):
4536class FirstValue(AggFunc):
4537    pass
key = 'firstvalue'
class LastValue(AggFunc):
4540class LastValue(AggFunc):
4541    pass
key = 'lastvalue'
class NthValue(AggFunc):
4544class NthValue(AggFunc):
4545    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4548class Case(Func):
4549    arg_types = {"this": False, "ifs": True, "default": False}
4550
4551    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4552        instance = maybe_copy(self, copy)
4553        instance.append(
4554            "ifs",
4555            If(
4556                this=maybe_parse(condition, copy=copy, **opts),
4557                true=maybe_parse(then, copy=copy, **opts),
4558            ),
4559        )
4560        return instance
4561
4562    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4563        instance = maybe_copy(self, copy)
4564        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4565        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:
4551    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4552        instance = maybe_copy(self, copy)
4553        instance.append(
4554            "ifs",
4555            If(
4556                this=maybe_parse(condition, copy=copy, **opts),
4557                true=maybe_parse(then, copy=copy, **opts),
4558            ),
4559        )
4560        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4562    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4563        instance = maybe_copy(self, copy)
4564        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4565        return instance
key = 'case'
class Cast(Func):
4568class Cast(Func):
4569    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4570
4571    @property
4572    def name(self) -> str:
4573        return self.this.name
4574
4575    @property
4576    def to(self) -> DataType:
4577        return self.args["to"]
4578
4579    @property
4580    def output_name(self) -> str:
4581        return self.name
4582
4583    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4584        """
4585        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4586        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4587        array<int> != array<float>.
4588
4589        Args:
4590            dtypes: the data types to compare this Cast's DataType to.
4591
4592        Returns:
4593            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4594        """
4595        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4571    @property
4572    def name(self) -> str:
4573        return self.this.name
to: DataType
4575    @property
4576    def to(self) -> DataType:
4577        return self.args["to"]
output_name: str
4579    @property
4580    def output_name(self) -> str:
4581        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:
4583    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4584        """
4585        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4586        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4587        array<int> != array<float>.
4588
4589        Args:
4590            dtypes: the data types to compare this Cast's DataType to.
4591
4592        Returns:
4593            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4594        """
4595        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):
4598class TryCast(Cast):
4599    pass
key = 'trycast'
class CastToStrType(Func):
4602class CastToStrType(Func):
4603    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4606class Collate(Binary, Func):
4607    pass
key = 'collate'
class Ceil(Func):
4610class Ceil(Func):
4611    arg_types = {"this": True, "decimals": False}
4612    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4615class Coalesce(Func):
4616    arg_types = {"this": True, "expressions": False}
4617    is_var_len_args = True
4618    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4621class Chr(Func):
4622    arg_types = {"this": True, "charset": False, "expressions": False}
4623    is_var_len_args = True
4624    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4627class Concat(Func):
4628    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4629    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4632class ConcatWs(Concat):
4633    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4636class Count(AggFunc):
4637    arg_types = {"this": False, "expressions": False}
4638    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4641class CountIf(AggFunc):
4642    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4646class Cbrt(Func):
4647    pass
key = 'cbrt'
class CurrentDate(Func):
4650class CurrentDate(Func):
4651    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4654class CurrentDatetime(Func):
4655    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4658class CurrentTime(Func):
4659    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4662class CurrentTimestamp(Func):
4663    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4666class CurrentUser(Func):
4667    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4670class DateAdd(Func, IntervalOp):
4671    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4674class DateSub(Func, IntervalOp):
4675    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4678class DateDiff(Func, TimeUnit):
4679    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4680    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4683class DateTrunc(Func):
4684    arg_types = {"unit": True, "this": True, "zone": False}
4685
4686    def __init__(self, **args):
4687        unit = args.get("unit")
4688        if isinstance(unit, TimeUnit.VAR_LIKE):
4689            args["unit"] = Literal.string(
4690                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4691            )
4692        elif isinstance(unit, Week):
4693            unit.set("this", Literal.string(unit.this.name.upper()))
4694
4695        super().__init__(**args)
4696
4697    @property
4698    def unit(self) -> Expression:
4699        return self.args["unit"]
DateTrunc(**args)
4686    def __init__(self, **args):
4687        unit = args.get("unit")
4688        if isinstance(unit, TimeUnit.VAR_LIKE):
4689            args["unit"] = Literal.string(
4690                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4691            )
4692        elif isinstance(unit, Week):
4693            unit.set("this", Literal.string(unit.this.name.upper()))
4694
4695        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4697    @property
4698    def unit(self) -> Expression:
4699        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4702class DatetimeAdd(Func, IntervalOp):
4703    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4706class DatetimeSub(Func, IntervalOp):
4707    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4710class DatetimeDiff(Func, TimeUnit):
4711    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4714class DatetimeTrunc(Func, TimeUnit):
4715    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4718class DayOfWeek(Func):
4719    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4722class DayOfMonth(Func):
4723    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4726class DayOfYear(Func):
4727    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4730class ToDays(Func):
4731    pass
key = 'todays'
class WeekOfYear(Func):
4734class WeekOfYear(Func):
4735    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4738class MonthsBetween(Func):
4739    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4742class LastDay(Func, TimeUnit):
4743    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4744    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4747class Extract(Func):
4748    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4751class Timestamp(Func):
4752    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4755class TimestampAdd(Func, TimeUnit):
4756    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4759class TimestampSub(Func, TimeUnit):
4760    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4763class TimestampDiff(Func, TimeUnit):
4764    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4765    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4768class TimestampTrunc(Func, TimeUnit):
4769    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4772class TimeAdd(Func, TimeUnit):
4773    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4776class TimeSub(Func, TimeUnit):
4777    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4780class TimeDiff(Func, TimeUnit):
4781    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4784class TimeTrunc(Func, TimeUnit):
4785    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4788class DateFromParts(Func):
4789    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4790    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4793class TimeFromParts(Func):
4794    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4795    arg_types = {
4796        "hour": True,
4797        "min": True,
4798        "sec": True,
4799        "nano": False,
4800        "fractions": False,
4801        "precision": False,
4802    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4805class DateStrToDate(Func):
4806    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4809class DateToDateStr(Func):
4810    pass
key = 'datetodatestr'
class DateToDi(Func):
4813class DateToDi(Func):
4814    pass
key = 'datetodi'
class Date(Func):
4818class Date(Func):
4819    arg_types = {"this": False, "zone": False, "expressions": False}
4820    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4823class Day(Func):
4824    pass
key = 'day'
class Decode(Func):
4827class Decode(Func):
4828    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4831class DiToDate(Func):
4832    pass
key = 'ditodate'
class Encode(Func):
4835class Encode(Func):
4836    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4839class Exp(Func):
4840    pass
key = 'exp'
class Explode(Func):
4844class Explode(Func):
4845    arg_types = {"this": True, "expressions": False}
4846    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4849class ExplodeOuter(Explode):
4850    pass
key = 'explodeouter'
class Posexplode(Explode):
4853class Posexplode(Explode):
4854    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4857class PosexplodeOuter(Posexplode, ExplodeOuter):
4858    pass
key = 'posexplodeouter'
class Floor(Func):
4861class Floor(Func):
4862    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4865class FromBase64(Func):
4866    pass
key = 'frombase64'
class ToBase64(Func):
4869class ToBase64(Func):
4870    pass
key = 'tobase64'
class Greatest(Func):
4873class Greatest(Func):
4874    arg_types = {"this": True, "expressions": False}
4875    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4878class GroupConcat(AggFunc):
4879    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4882class Hex(Func):
4883    pass
key = 'hex'
class Xor(Connector, Func):
4886class Xor(Connector, Func):
4887    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4890class If(Func):
4891    arg_types = {"this": True, "true": True, "false": False}
4892    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4895class Nullif(Func):
4896    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4899class Initcap(Func):
4900    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4903class IsNan(Func):
4904    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4907class IsInf(Func):
4908    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
4911class JSONPath(Expression):
4912    arg_types = {"expressions": True}
4913
4914    @property
4915    def output_name(self) -> str:
4916        last_segment = self.expressions[-1].this
4917        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
4914    @property
4915    def output_name(self) -> str:
4916        last_segment = self.expressions[-1].this
4917        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):
4920class JSONPathPart(Expression):
4921    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
4924class JSONPathFilter(JSONPathPart):
4925    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
4928class JSONPathKey(JSONPathPart):
4929    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
4932class JSONPathRecursive(JSONPathPart):
4933    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
4936class JSONPathRoot(JSONPathPart):
4937    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
4940class JSONPathScript(JSONPathPart):
4941    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
4944class JSONPathSlice(JSONPathPart):
4945    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
4948class JSONPathSelector(JSONPathPart):
4949    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
4952class JSONPathSubscript(JSONPathPart):
4953    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
4956class JSONPathUnion(JSONPathPart):
4957    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
4960class JSONPathWildcard(JSONPathPart):
4961    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
4964class FormatJson(Expression):
4965    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4968class JSONKeyValue(Expression):
4969    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4972class JSONObject(Func):
4973    arg_types = {
4974        "expressions": False,
4975        "null_handling": False,
4976        "unique_keys": False,
4977        "return_type": False,
4978        "encoding": False,
4979    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4982class JSONObjectAgg(AggFunc):
4983    arg_types = {
4984        "expressions": False,
4985        "null_handling": False,
4986        "unique_keys": False,
4987        "return_type": False,
4988        "encoding": False,
4989    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4993class JSONArray(Func):
4994    arg_types = {
4995        "expressions": True,
4996        "null_handling": False,
4997        "return_type": False,
4998        "strict": False,
4999    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5003class JSONArrayAgg(Func):
5004    arg_types = {
5005        "this": True,
5006        "order": False,
5007        "null_handling": False,
5008        "return_type": False,
5009        "strict": False,
5010    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5015class JSONColumnDef(Expression):
5016    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):
5019class JSONSchema(Expression):
5020    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5024class JSONTable(Func):
5025    arg_types = {
5026        "this": True,
5027        "schema": True,
5028        "path": False,
5029        "error_handling": False,
5030        "empty_handling": False,
5031    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5034class OpenJSONColumnDef(Expression):
5035    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):
5038class OpenJSON(Func):
5039    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5042class JSONBContains(Binary):
5043    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5046class JSONExtract(Binary, Func):
5047    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5048    _sql_names = ["JSON_EXTRACT"]
5049    is_var_len_args = True
5050
5051    @property
5052    def output_name(self) -> str:
5053        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
5051    @property
5052    def output_name(self) -> str:
5053        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):
5056class JSONExtractScalar(Binary, Func):
5057    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5058    _sql_names = ["JSON_EXTRACT_SCALAR"]
5059    is_var_len_args = True
5060
5061    @property
5062    def output_name(self) -> str:
5063        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
5061    @property
5062    def output_name(self) -> str:
5063        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):
5066class JSONBExtract(Binary, Func):
5067    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5070class JSONBExtractScalar(Binary, Func):
5071    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5074class JSONFormat(Func):
5075    arg_types = {"this": False, "options": False}
5076    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5080class JSONArrayContains(Binary, Predicate, Func):
5081    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5084class ParseJSON(Func):
5085    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5086    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5087    arg_types = {"this": True, "expressions": False}
5088    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5091class Least(Func):
5092    arg_types = {"this": True, "expressions": False}
5093    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5096class Left(Func):
5097    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5104class Length(Func):
5105    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5108class Levenshtein(Func):
5109    arg_types = {
5110        "this": True,
5111        "expression": False,
5112        "ins_cost": False,
5113        "del_cost": False,
5114        "sub_cost": False,
5115    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5118class Ln(Func):
5119    pass
key = 'ln'
class Log(Func):
5122class Log(Func):
5123    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5126class Log2(Func):
5127    pass
key = 'log2'
class Log10(Func):
5130class Log10(Func):
5131    pass
key = 'log10'
class LogicalOr(AggFunc):
5134class LogicalOr(AggFunc):
5135    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5138class LogicalAnd(AggFunc):
5139    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5142class Lower(Func):
5143    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5146class Map(Func):
5147    arg_types = {"keys": False, "values": False}
5148
5149    @property
5150    def keys(self) -> t.List[Expression]:
5151        keys = self.args.get("keys")
5152        return keys.expressions if keys else []
5153
5154    @property
5155    def values(self) -> t.List[Expression]:
5156        values = self.args.get("values")
5157        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5149    @property
5150    def keys(self) -> t.List[Expression]:
5151        keys = self.args.get("keys")
5152        return keys.expressions if keys else []
values: List[Expression]
5154    @property
5155    def values(self) -> t.List[Expression]:
5156        values = self.args.get("values")
5157        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5160class MapFromEntries(Func):
5161    pass
key = 'mapfromentries'
class StarMap(Func):
5164class StarMap(Func):
5165    pass
key = 'starmap'
class VarMap(Func):
5168class VarMap(Func):
5169    arg_types = {"keys": True, "values": True}
5170    is_var_len_args = True
5171
5172    @property
5173    def keys(self) -> t.List[Expression]:
5174        return self.args["keys"].expressions
5175
5176    @property
5177    def values(self) -> t.List[Expression]:
5178        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5172    @property
5173    def keys(self) -> t.List[Expression]:
5174        return self.args["keys"].expressions
values: List[Expression]
5176    @property
5177    def values(self) -> t.List[Expression]:
5178        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5182class MatchAgainst(Func):
5183    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5186class Max(AggFunc):
5187    arg_types = {"this": True, "expressions": False}
5188    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5191class MD5(Func):
5192    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5196class MD5Digest(Func):
5197    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5200class Min(AggFunc):
5201    arg_types = {"this": True, "expressions": False}
5202    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5205class Month(Func):
5206    pass
key = 'month'
class AddMonths(Func):
5209class AddMonths(Func):
5210    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5213class Nvl2(Func):
5214    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5218class Predict(Func):
5219    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5222class Pow(Binary, Func):
5223    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5226class PercentileCont(AggFunc):
5227    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5230class PercentileDisc(AggFunc):
5231    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5234class Quantile(AggFunc):
5235    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5238class ApproxQuantile(Quantile):
5239    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):
5242class Rand(Func):
5243    _sql_names = ["RAND", "RANDOM"]
5244    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5247class Randn(Func):
5248    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5251class RangeN(Func):
5252    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5255class ReadCSV(Func):
5256    _sql_names = ["READ_CSV"]
5257    is_var_len_args = True
5258    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5261class Reduce(Func):
5262    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):
5265class RegexpExtract(Func):
5266    arg_types = {
5267        "this": True,
5268        "expression": True,
5269        "position": False,
5270        "occurrence": False,
5271        "parameters": False,
5272        "group": False,
5273    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5276class RegexpReplace(Func):
5277    arg_types = {
5278        "this": True,
5279        "expression": True,
5280        "replacement": False,
5281        "position": False,
5282        "occurrence": False,
5283        "parameters": False,
5284        "modifiers": False,
5285    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5288class RegexpLike(Binary, Func):
5289    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5292class RegexpILike(Binary, Func):
5293    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5298class RegexpSplit(Func):
5299    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5302class Repeat(Func):
5303    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5308class Round(Func):
5309    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5312class RowNumber(Func):
5313    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5316class SafeDivide(Func):
5317    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5320class SHA(Func):
5321    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5324class SHA2(Func):
5325    _sql_names = ["SHA2"]
5326    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5329class Sign(Func):
5330    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5333class SortArray(Func):
5334    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5337class Split(Func):
5338    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5343class Substring(Func):
5344    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5347class StandardHash(Func):
5348    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5351class StartsWith(Func):
5352    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5353    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5356class StrPosition(Func):
5357    arg_types = {
5358        "this": True,
5359        "substr": True,
5360        "position": False,
5361        "instance": False,
5362    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5365class StrToDate(Func):
5366    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5369class StrToTime(Func):
5370    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5375class StrToUnix(Func):
5376    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5381class StrToMap(Func):
5382    arg_types = {
5383        "this": True,
5384        "pair_delim": False,
5385        "key_value_delim": False,
5386        "duplicate_resolution_callback": False,
5387    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5390class NumberToStr(Func):
5391    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5394class FromBase(Func):
5395    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5398class Struct(Func):
5399    arg_types = {"expressions": False}
5400    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5403class StructExtract(Func):
5404    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5409class Stuff(Func):
5410    _sql_names = ["STUFF", "INSERT"]
5411    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):
5414class Sum(AggFunc):
5415    pass
key = 'sum'
class Sqrt(Func):
5418class Sqrt(Func):
5419    pass
key = 'sqrt'
class Stddev(AggFunc):
5422class Stddev(AggFunc):
5423    pass
key = 'stddev'
class StddevPop(AggFunc):
5426class StddevPop(AggFunc):
5427    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5430class StddevSamp(AggFunc):
5431    pass
key = 'stddevsamp'
class TimeToStr(Func):
5434class TimeToStr(Func):
5435    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5438class TimeToTimeStr(Func):
5439    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5442class TimeToUnix(Func):
5443    pass
key = 'timetounix'
class TimeStrToDate(Func):
5446class TimeStrToDate(Func):
5447    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5450class TimeStrToTime(Func):
5451    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5454class TimeStrToUnix(Func):
5455    pass
key = 'timestrtounix'
class Trim(Func):
5458class Trim(Func):
5459    arg_types = {
5460        "this": True,
5461        "expression": False,
5462        "position": False,
5463        "collation": False,
5464    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5467class TsOrDsAdd(Func, TimeUnit):
5468    # return_type is used to correctly cast the arguments of this expression when transpiling it
5469    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5470
5471    @property
5472    def return_type(self) -> DataType:
5473        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
5471    @property
5472    def return_type(self) -> DataType:
5473        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5476class TsOrDsDiff(Func, TimeUnit):
5477    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5480class TsOrDsToDateStr(Func):
5481    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5484class TsOrDsToDate(Func):
5485    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5488class TsOrDsToTime(Func):
5489    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5492class TsOrDiToDi(Func):
5493    pass
key = 'tsorditodi'
class Unhex(Func):
5496class Unhex(Func):
5497    pass
key = 'unhex'
class UnixDate(Func):
5501class UnixDate(Func):
5502    pass
key = 'unixdate'
class UnixToStr(Func):
5505class UnixToStr(Func):
5506    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5511class UnixToTime(Func):
5512    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5513
5514    SECONDS = Literal.number(0)
5515    DECIS = Literal.number(1)
5516    CENTIS = Literal.number(2)
5517    MILLIS = Literal.number(3)
5518    DECIMILLIS = Literal.number(4)
5519    CENTIMILLIS = Literal.number(5)
5520    MICROS = Literal.number(6)
5521    DECIMICROS = Literal.number(7)
5522    CENTIMICROS = Literal.number(8)
5523    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):
5526class UnixToTimeStr(Func):
5527    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5530class TimestampFromParts(Func):
5531    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5532    arg_types = {
5533        "year": True,
5534        "month": True,
5535        "day": True,
5536        "hour": True,
5537        "min": True,
5538        "sec": True,
5539        "nano": False,
5540        "zone": False,
5541        "milli": False,
5542    }
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):
5545class Upper(Func):
5546    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5549class Variance(AggFunc):
5550    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5553class VariancePop(AggFunc):
5554    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5557class Week(Func):
5558    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5561class XMLTable(Func):
5562    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):
5565class Year(Func):
5566    pass
key = 'year'
class Use(Expression):
5569class Use(Expression):
5570    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5573class Merge(Expression):
5574    arg_types = {
5575        "this": True,
5576        "using": True,
5577        "on": True,
5578        "expressions": True,
5579        "with": False,
5580    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5583class When(Func):
5584    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):
5589class NextValueFor(Func):
5590    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 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, '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:
5630def maybe_parse(
5631    sql_or_expression: ExpOrStr,
5632    *,
5633    into: t.Optional[IntoType] = None,
5634    dialect: DialectType = None,
5635    prefix: t.Optional[str] = None,
5636    copy: bool = False,
5637    **opts,
5638) -> Expression:
5639    """Gracefully handle a possible string or expression.
5640
5641    Example:
5642        >>> maybe_parse("1")
5643        Literal(this=1, is_string=False)
5644        >>> maybe_parse(to_identifier("x"))
5645        Identifier(this=x, quoted=False)
5646
5647    Args:
5648        sql_or_expression: the SQL code string or an expression
5649        into: the SQLGlot Expression to parse into
5650        dialect: the dialect used to parse the input expressions (in the case that an
5651            input expression is a SQL string).
5652        prefix: a string to prefix the sql with before it gets parsed
5653            (automatically includes a space)
5654        copy: whether to copy the expression.
5655        **opts: other options to use to parse the input expressions (again, in the case
5656            that an input expression is a SQL string).
5657
5658    Returns:
5659        Expression: the parsed or given expression.
5660    """
5661    if isinstance(sql_or_expression, Expression):
5662        if copy:
5663            return sql_or_expression.copy()
5664        return sql_or_expression
5665
5666    if sql_or_expression is None:
5667        raise ParseError("SQL cannot be None")
5668
5669    import sqlglot
5670
5671    sql = str(sql_or_expression)
5672    if prefix:
5673        sql = f"{prefix} {sql}"
5674
5675    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):
5688def maybe_copy(instance, copy=True):
5689    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:
5903def union(
5904    left: ExpOrStr,
5905    right: ExpOrStr,
5906    distinct: bool = True,
5907    dialect: DialectType = None,
5908    copy: bool = True,
5909    **opts,
5910) -> Union:
5911    """
5912    Initializes a syntax tree from one UNION expression.
5913
5914    Example:
5915        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5916        'SELECT * FROM foo UNION SELECT * FROM bla'
5917
5918    Args:
5919        left: the SQL code string corresponding to the left-hand side.
5920            If an `Expression` instance is passed, it will be used as-is.
5921        right: the SQL code string corresponding to the right-hand side.
5922            If an `Expression` instance is passed, it will be used as-is.
5923        distinct: set the DISTINCT flag if and only if this is true.
5924        dialect: the dialect used to parse the input expression.
5925        copy: whether to copy the expression.
5926        opts: other options to use to parse the input expressions.
5927
5928    Returns:
5929        The new Union instance.
5930    """
5931    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5932    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5933
5934    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:
5937def intersect(
5938    left: ExpOrStr,
5939    right: ExpOrStr,
5940    distinct: bool = True,
5941    dialect: DialectType = None,
5942    copy: bool = True,
5943    **opts,
5944) -> Intersect:
5945    """
5946    Initializes a syntax tree from one INTERSECT expression.
5947
5948    Example:
5949        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5950        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5951
5952    Args:
5953        left: the SQL code string corresponding to the left-hand side.
5954            If an `Expression` instance is passed, it will be used as-is.
5955        right: the SQL code string corresponding to the right-hand side.
5956            If an `Expression` instance is passed, it will be used as-is.
5957        distinct: set the DISTINCT flag if and only if this is true.
5958        dialect: the dialect used to parse the input expression.
5959        copy: whether to copy the expression.
5960        opts: other options to use to parse the input expressions.
5961
5962    Returns:
5963        The new Intersect instance.
5964    """
5965    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5966    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5967
5968    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:
5971def except_(
5972    left: ExpOrStr,
5973    right: ExpOrStr,
5974    distinct: bool = True,
5975    dialect: DialectType = None,
5976    copy: bool = True,
5977    **opts,
5978) -> Except:
5979    """
5980    Initializes a syntax tree from one EXCEPT expression.
5981
5982    Example:
5983        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5984        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5985
5986    Args:
5987        left: the SQL code string corresponding to the left-hand side.
5988            If an `Expression` instance is passed, it will be used as-is.
5989        right: the SQL code string corresponding to the right-hand side.
5990            If an `Expression` instance is passed, it will be used as-is.
5991        distinct: set the DISTINCT flag if and only if this is true.
5992        dialect: the dialect used to parse the input expression.
5993        copy: whether to copy the expression.
5994        opts: other options to use to parse the input expressions.
5995
5996    Returns:
5997        The new Except instance.
5998    """
5999    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6000    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6001
6002    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:
6005def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6006    """
6007    Initializes a syntax tree from one or multiple SELECT expressions.
6008
6009    Example:
6010        >>> select("col1", "col2").from_("tbl").sql()
6011        'SELECT col1, col2 FROM tbl'
6012
6013    Args:
6014        *expressions: the SQL code string to parse as the expressions of a
6015            SELECT statement. If an Expression instance is passed, this is used as-is.
6016        dialect: the dialect used to parse the input expressions (in the case that an
6017            input expression is a SQL string).
6018        **opts: other options to use to parse the input expressions (again, in the case
6019            that an input expression is a SQL string).
6020
6021    Returns:
6022        Select: the syntax tree for the SELECT statement.
6023    """
6024    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:
6027def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6028    """
6029    Initializes a syntax tree from a FROM expression.
6030
6031    Example:
6032        >>> from_("tbl").select("col1", "col2").sql()
6033        'SELECT col1, col2 FROM tbl'
6034
6035    Args:
6036        *expression: the SQL code string to parse as the FROM expressions of a
6037            SELECT statement. If an Expression instance is passed, this is used as-is.
6038        dialect: the dialect used to parse the input expression (in the case that the
6039            input expression is a SQL string).
6040        **opts: other options to use to parse the input expressions (again, in the case
6041            that the input expression is a SQL string).
6042
6043    Returns:
6044        Select: the syntax tree for the SELECT statement.
6045    """
6046    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:
6049def update(
6050    table: str | Table,
6051    properties: dict,
6052    where: t.Optional[ExpOrStr] = None,
6053    from_: t.Optional[ExpOrStr] = None,
6054    dialect: DialectType = None,
6055    **opts,
6056) -> Update:
6057    """
6058    Creates an update statement.
6059
6060    Example:
6061        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6062        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6063
6064    Args:
6065        *properties: dictionary of properties to set which are
6066            auto converted to sql objects eg None -> NULL
6067        where: sql conditional parsed into a WHERE statement
6068        from_: sql statement parsed into a FROM statement
6069        dialect: the dialect used to parse the input expressions.
6070        **opts: other options to use to parse the input expressions.
6071
6072    Returns:
6073        Update: the syntax tree for the UPDATE statement.
6074    """
6075    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6076    update_expr.set(
6077        "expressions",
6078        [
6079            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6080            for k, v in properties.items()
6081        ],
6082    )
6083    if from_:
6084        update_expr.set(
6085            "from",
6086            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6087        )
6088    if isinstance(where, Condition):
6089        where = Where(this=where)
6090    if where:
6091        update_expr.set(
6092            "where",
6093            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6094        )
6095    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:
6098def delete(
6099    table: ExpOrStr,
6100    where: t.Optional[ExpOrStr] = None,
6101    returning: t.Optional[ExpOrStr] = None,
6102    dialect: DialectType = None,
6103    **opts,
6104) -> Delete:
6105    """
6106    Builds a delete statement.
6107
6108    Example:
6109        >>> delete("my_table", where="id > 1").sql()
6110        'DELETE FROM my_table WHERE id > 1'
6111
6112    Args:
6113        where: sql conditional parsed into a WHERE statement
6114        returning: sql conditional parsed into a RETURNING statement
6115        dialect: the dialect used to parse the input expressions.
6116        **opts: other options to use to parse the input expressions.
6117
6118    Returns:
6119        Delete: the syntax tree for the DELETE statement.
6120    """
6121    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6122    if where:
6123        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6124    if returning:
6125        delete_expr = t.cast(
6126            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6127        )
6128    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:
6131def insert(
6132    expression: ExpOrStr,
6133    into: ExpOrStr,
6134    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6135    overwrite: t.Optional[bool] = None,
6136    returning: t.Optional[ExpOrStr] = None,
6137    dialect: DialectType = None,
6138    copy: bool = True,
6139    **opts,
6140) -> Insert:
6141    """
6142    Builds an INSERT statement.
6143
6144    Example:
6145        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6146        'INSERT INTO tbl VALUES (1, 2, 3)'
6147
6148    Args:
6149        expression: the sql string or expression of the INSERT statement
6150        into: the tbl to insert data to.
6151        columns: optionally the table's column names.
6152        overwrite: whether to INSERT OVERWRITE or not.
6153        returning: sql conditional parsed into a RETURNING statement
6154        dialect: the dialect used to parse the input expressions.
6155        copy: whether to copy the expression.
6156        **opts: other options to use to parse the input expressions.
6157
6158    Returns:
6159        Insert: the syntax tree for the INSERT statement.
6160    """
6161    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6162    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6163
6164    if columns:
6165        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6166
6167    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6168
6169    if returning:
6170        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6171
6172    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:
6175def condition(
6176    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6177) -> Condition:
6178    """
6179    Initialize a logical condition expression.
6180
6181    Example:
6182        >>> condition("x=1").sql()
6183        'x = 1'
6184
6185        This is helpful for composing larger logical syntax trees:
6186        >>> where = condition("x=1")
6187        >>> where = where.and_("y=1")
6188        >>> Select().from_("tbl").select("*").where(where).sql()
6189        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6190
6191    Args:
6192        *expression: the SQL code string to parse.
6193            If an Expression instance is passed, this is used as-is.
6194        dialect: the dialect used to parse the input expression (in the case that the
6195            input expression is a SQL string).
6196        copy: Whether to copy `expression` (only applies to expressions).
6197        **opts: other options to use to parse the input expressions (again, in the case
6198            that the input expression is a SQL string).
6199
6200    Returns:
6201        The new Condition instance
6202    """
6203    return maybe_parse(
6204        expression,
6205        into=Condition,
6206        dialect=dialect,
6207        copy=copy,
6208        **opts,
6209    )

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:
6212def and_(
6213    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6214) -> Condition:
6215    """
6216    Combine multiple conditions with an AND logical operator.
6217
6218    Example:
6219        >>> and_("x=1", and_("y=1", "z=1")).sql()
6220        'x = 1 AND (y = 1 AND z = 1)'
6221
6222    Args:
6223        *expressions: the SQL code strings to parse.
6224            If an Expression instance is passed, this is used as-is.
6225        dialect: the dialect used to parse the input expression.
6226        copy: whether to copy `expressions` (only applies to Expressions).
6227        **opts: other options to use to parse the input expressions.
6228
6229    Returns:
6230        And: the new condition
6231    """
6232    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:
6235def or_(
6236    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6237) -> Condition:
6238    """
6239    Combine multiple conditions with an OR logical operator.
6240
6241    Example:
6242        >>> or_("x=1", or_("y=1", "z=1")).sql()
6243        'x = 1 OR (y = 1 OR z = 1)'
6244
6245    Args:
6246        *expressions: the SQL code strings to parse.
6247            If an Expression instance is passed, this is used as-is.
6248        dialect: the dialect used to parse the input expression.
6249        copy: whether to copy `expressions` (only applies to Expressions).
6250        **opts: other options to use to parse the input expressions.
6251
6252    Returns:
6253        Or: the new condition
6254    """
6255    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:
6258def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6259    """
6260    Wrap a condition with a NOT operator.
6261
6262    Example:
6263        >>> not_("this_suit='black'").sql()
6264        "NOT this_suit = 'black'"
6265
6266    Args:
6267        expression: the SQL code string to parse.
6268            If an Expression instance is passed, this is used as-is.
6269        dialect: the dialect used to parse the input expression.
6270        copy: whether to copy the expression or not.
6271        **opts: other options to use to parse the input expressions.
6272
6273    Returns:
6274        The new condition.
6275    """
6276    this = condition(
6277        expression,
6278        dialect=dialect,
6279        copy=copy,
6280        **opts,
6281    )
6282    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:
6285def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6286    """
6287    Wrap an expression in parentheses.
6288
6289    Example:
6290        >>> paren("5 + 3").sql()
6291        '(5 + 3)'
6292
6293    Args:
6294        expression: the SQL code string to parse.
6295            If an Expression instance is passed, this is used as-is.
6296        copy: whether to copy the expression or not.
6297
6298    Returns:
6299        The wrapped expression.
6300    """
6301    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):
6319def to_identifier(name, quoted=None, copy=True):
6320    """Builds an identifier.
6321
6322    Args:
6323        name: The name to turn into an identifier.
6324        quoted: Whether to force quote the identifier.
6325        copy: Whether to copy name if it's an Identifier.
6326
6327    Returns:
6328        The identifier ast node.
6329    """
6330
6331    if name is None:
6332        return None
6333
6334    if isinstance(name, Identifier):
6335        identifier = maybe_copy(name, copy)
6336    elif isinstance(name, str):
6337        identifier = Identifier(
6338            this=name,
6339            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6340        )
6341    else:
6342        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6343    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:
6346def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6347    """
6348    Parses a given string into an identifier.
6349
6350    Args:
6351        name: The name to parse into an identifier.
6352        dialect: The dialect to parse against.
6353
6354    Returns:
6355        The identifier ast node.
6356    """
6357    try:
6358        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6359    except ParseError:
6360        expression = to_identifier(name)
6361
6362    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:
6368def to_interval(interval: str | Literal) -> Interval:
6369    """Builds an interval expression from a string like '1 day' or '5 months'."""
6370    if isinstance(interval, Literal):
6371        if not interval.is_string:
6372            raise ValueError("Invalid interval string.")
6373
6374        interval = interval.this
6375
6376    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6377
6378    if not interval_parts:
6379        raise ValueError("Invalid interval string.")
6380
6381    return Interval(
6382        this=Literal.string(interval_parts.group(1)),
6383        unit=Var(this=interval_parts.group(2).upper()),
6384    )

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]:
6397def to_table(
6398    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6399) -> t.Optional[Table]:
6400    """
6401    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6402    If a table is passed in then that table is returned.
6403
6404    Args:
6405        sql_path: a `[catalog].[schema].[table]` string.
6406        dialect: the source dialect according to which the table name will be parsed.
6407        copy: Whether to copy a table if it is passed in.
6408        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6409
6410    Returns:
6411        A table expression.
6412    """
6413    if sql_path is None or isinstance(sql_path, Table):
6414        return maybe_copy(sql_path, copy=copy)
6415    if not isinstance(sql_path, str):
6416        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6417
6418    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6419    if table:
6420        for k, v in kwargs.items():
6421            table.set(k, v)
6422
6423    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:
6426def to_column(sql_path: str | Column, **kwargs) -> Column:
6427    """
6428    Create a column from a `[table].[column]` sql path. Schema is optional.
6429
6430    If a column is passed in then that column is returned.
6431
6432    Args:
6433        sql_path: `[table].[column]` string
6434    Returns:
6435        Table: A column expression
6436    """
6437    if sql_path is None or isinstance(sql_path, Column):
6438        return sql_path
6439    if not isinstance(sql_path, str):
6440        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6441    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):
6444def alias_(
6445    expression: ExpOrStr,
6446    alias: t.Optional[str | Identifier],
6447    table: bool | t.Sequence[str | Identifier] = False,
6448    quoted: t.Optional[bool] = None,
6449    dialect: DialectType = None,
6450    copy: bool = True,
6451    **opts,
6452):
6453    """Create an Alias expression.
6454
6455    Example:
6456        >>> alias_('foo', 'bar').sql()
6457        'foo AS bar'
6458
6459        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6460        '(SELECT 1, 2) AS bar(a, b)'
6461
6462    Args:
6463        expression: the SQL code strings to parse.
6464            If an Expression instance is passed, this is used as-is.
6465        alias: the alias name to use. If the name has
6466            special characters it is quoted.
6467        table: Whether to create a table alias, can also be a list of columns.
6468        quoted: whether to quote the alias
6469        dialect: the dialect used to parse the input expression.
6470        copy: Whether to copy the expression.
6471        **opts: other options to use to parse the input expressions.
6472
6473    Returns:
6474        Alias: the aliased expression
6475    """
6476    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6477    alias = to_identifier(alias, quoted=quoted)
6478
6479    if table:
6480        table_alias = TableAlias(this=alias)
6481        exp.set("alias", table_alias)
6482
6483        if not isinstance(table, bool):
6484            for column in table:
6485                table_alias.append("columns", to_identifier(column, quoted=quoted))
6486
6487        return exp
6488
6489    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6490    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6491    # for the complete Window expression.
6492    #
6493    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6494
6495    if "alias" in exp.arg_types and not isinstance(exp, Window):
6496        exp.set("alias", alias)
6497        return exp
6498    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:
6501def subquery(
6502    expression: ExpOrStr,
6503    alias: t.Optional[Identifier | str] = None,
6504    dialect: DialectType = None,
6505    **opts,
6506) -> Select:
6507    """
6508    Build a subquery expression.
6509
6510    Example:
6511        >>> subquery('select x from tbl', 'bar').select('x').sql()
6512        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6513
6514    Args:
6515        expression: the SQL code strings to parse.
6516            If an Expression instance is passed, this is used as-is.
6517        alias: the alias name to use.
6518        dialect: the dialect used to parse the input expression.
6519        **opts: other options to use to parse the input expressions.
6520
6521    Returns:
6522        A new Select instance with the subquery expression included.
6523    """
6524
6525    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6526    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):
6557def column(
6558    col,
6559    table=None,
6560    db=None,
6561    catalog=None,
6562    *,
6563    fields=None,
6564    quoted=None,
6565    copy=True,
6566):
6567    """
6568    Build a Column.
6569
6570    Args:
6571        col: Column name.
6572        table: Table name.
6573        db: Database name.
6574        catalog: Catalog name.
6575        fields: Additional fields using dots.
6576        quoted: Whether to force quotes on the column's identifiers.
6577        copy: Whether to copy identifiers if passed in.
6578
6579    Returns:
6580        The new Column instance.
6581    """
6582    this = Column(
6583        this=to_identifier(col, quoted=quoted, copy=copy),
6584        table=to_identifier(table, quoted=quoted, copy=copy),
6585        db=to_identifier(db, quoted=quoted, copy=copy),
6586        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6587    )
6588
6589    if fields:
6590        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6591    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:
6594def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6595    """Cast an expression to a data type.
6596
6597    Example:
6598        >>> cast('x + 1', 'int').sql()
6599        'CAST(x + 1 AS INT)'
6600
6601    Args:
6602        expression: The expression to cast.
6603        to: The datatype to cast to.
6604        copy: Whether to copy the supplied expressions.
6605
6606    Returns:
6607        The new Cast instance.
6608    """
6609    expression = maybe_parse(expression, copy=copy, **opts)
6610    data_type = DataType.build(to, copy=copy, **opts)
6611    expression = Cast(this=expression, to=data_type)
6612    expression.type = data_type
6613    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:
6616def table_(
6617    table: Identifier | str,
6618    db: t.Optional[Identifier | str] = None,
6619    catalog: t.Optional[Identifier | str] = None,
6620    quoted: t.Optional[bool] = None,
6621    alias: t.Optional[Identifier | str] = None,
6622) -> Table:
6623    """Build a Table.
6624
6625    Args:
6626        table: Table name.
6627        db: Database name.
6628        catalog: Catalog name.
6629        quote: Whether to force quotes on the table's identifiers.
6630        alias: Table's alias.
6631
6632    Returns:
6633        The new Table instance.
6634    """
6635    return Table(
6636        this=to_identifier(table, quoted=quoted) if table else None,
6637        db=to_identifier(db, quoted=quoted) if db else None,
6638        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6639        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6640    )

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

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:
6676def var(name: t.Optional[ExpOrStr]) -> Var:
6677    """Build a SQL variable.
6678
6679    Example:
6680        >>> repr(var('x'))
6681        'Var(this=x)'
6682
6683        >>> repr(var(column('x', table='y')))
6684        'Var(this=x)'
6685
6686    Args:
6687        name: The name of the var or an expression who's name will become the var.
6688
6689    Returns:
6690        The new variable node.
6691    """
6692    if not name:
6693        raise ValueError("Cannot convert empty name into var.")
6694
6695    if isinstance(name, Expression):
6696        name = name.name
6697    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:
6700def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6701    """Build ALTER TABLE... RENAME... expression
6702
6703    Args:
6704        old_name: The old name of the table
6705        new_name: The new name of the table
6706
6707    Returns:
6708        Alter table expression
6709    """
6710    old_table = to_table(old_name)
6711    new_table = to_table(new_name)
6712    return AlterTable(
6713        this=old_table,
6714        actions=[
6715            RenameTable(this=new_table),
6716        ],
6717    )

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:
6720def rename_column(
6721    table_name: str | Table,
6722    old_column_name: str | Column,
6723    new_column_name: str | Column,
6724    exists: t.Optional[bool] = None,
6725) -> AlterTable:
6726    """Build ALTER TABLE... RENAME COLUMN... expression
6727
6728    Args:
6729        table_name: Name of the table
6730        old_column: The old name of the column
6731        new_column: The new name of the column
6732        exists: Whether to add the `IF EXISTS` clause
6733
6734    Returns:
6735        Alter table expression
6736    """
6737    table = to_table(table_name)
6738    old_column = to_column(old_column_name)
6739    new_column = to_column(new_column_name)
6740    return AlterTable(
6741        this=table,
6742        actions=[
6743            RenameColumn(this=old_column, to=new_column, exists=exists),
6744        ],
6745    )

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:
6748def convert(value: t.Any, copy: bool = False) -> Expression:
6749    """Convert a python value into an expression object.
6750
6751    Raises an error if a conversion is not possible.
6752
6753    Args:
6754        value: A python object.
6755        copy: Whether to copy `value` (only applies to Expressions and collections).
6756
6757    Returns:
6758        Expression: the equivalent expression object.
6759    """
6760    if isinstance(value, Expression):
6761        return maybe_copy(value, copy)
6762    if isinstance(value, str):
6763        return Literal.string(value)
6764    if isinstance(value, bool):
6765        return Boolean(this=value)
6766    if value is None or (isinstance(value, float) and math.isnan(value)):
6767        return null()
6768    if isinstance(value, numbers.Number):
6769        return Literal.number(value)
6770    if isinstance(value, datetime.datetime):
6771        datetime_literal = Literal.string(
6772            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6773        )
6774        return TimeStrToTime(this=datetime_literal)
6775    if isinstance(value, datetime.date):
6776        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6777        return DateStrToDate(this=date_literal)
6778    if isinstance(value, tuple):
6779        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6780    if isinstance(value, list):
6781        return Array(expressions=[convert(v, copy=copy) for v in value])
6782    if isinstance(value, dict):
6783        return Map(
6784            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6785            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6786        )
6787    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:
6790def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6791    """
6792    Replace children of an expression with the result of a lambda fun(child) -> exp.
6793    """
6794    for k, v in expression.args.items():
6795        is_list_arg = type(v) is list
6796
6797        child_nodes = v if is_list_arg else [v]
6798        new_child_nodes = []
6799
6800        for cn in child_nodes:
6801            if isinstance(cn, Expression):
6802                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6803                    new_child_nodes.append(child_node)
6804                    child_node.parent = expression
6805                    child_node.arg_key = k
6806            else:
6807                new_child_nodes.append(cn)
6808
6809        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]:
6812def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6813    """
6814    Return all table names referenced through columns in an expression.
6815
6816    Example:
6817        >>> import sqlglot
6818        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6819        ['a', 'c']
6820
6821    Args:
6822        expression: expression to find table names.
6823        exclude: a table name to exclude
6824
6825    Returns:
6826        A list of unique names.
6827    """
6828    return {
6829        table
6830        for table in (column.table for column in expression.find_all(Column))
6831        if table and table != exclude
6832    }

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

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:
6869def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6870    """Returns a case normalized table name without quotes.
6871
6872    Args:
6873        table: the table to normalize
6874        dialect: the dialect to use for normalization rules
6875        copy: whether to copy the expression.
6876
6877    Examples:
6878        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6879        'A-B.c'
6880    """
6881    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6882
6883    return ".".join(
6884        p.name
6885        for p in normalize_identifiers(
6886            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6887        ).parts
6888    )

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:
6891def replace_tables(
6892    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6893) -> E:
6894    """Replace all tables in expression according to the mapping.
6895
6896    Args:
6897        expression: expression node to be transformed and replaced.
6898        mapping: mapping of table names.
6899        dialect: the dialect of the mapping table
6900        copy: whether to copy the expression.
6901
6902    Examples:
6903        >>> from sqlglot import exp, parse_one
6904        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6905        'SELECT * FROM c /* a.b */'
6906
6907    Returns:
6908        The mapped expression.
6909    """
6910
6911    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6912
6913    def _replace_tables(node: Expression) -> Expression:
6914        if isinstance(node, Table):
6915            original = normalize_table_name(node, dialect=dialect)
6916            new_name = mapping.get(original)
6917
6918            if new_name:
6919                table = to_table(
6920                    new_name,
6921                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6922                    dialect=dialect,
6923                )
6924                table.add_comments([original])
6925                return table
6926        return node
6927
6928    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:
6931def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6932    """Replace placeholders in an expression.
6933
6934    Args:
6935        expression: expression node to be transformed and replaced.
6936        args: positional names that will substitute unnamed placeholders in the given order.
6937        kwargs: keyword arguments that will substitute named placeholders.
6938
6939    Examples:
6940        >>> from sqlglot import exp, parse_one
6941        >>> replace_placeholders(
6942        ...     parse_one("select * from :tbl where ? = ?"),
6943        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6944        ... ).sql()
6945        "SELECT * FROM foo WHERE str_col = 'b'"
6946
6947    Returns:
6948        The mapped expression.
6949    """
6950
6951    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6952        if isinstance(node, Placeholder):
6953            if node.name:
6954                new_name = kwargs.get(node.name)
6955                if new_name is not None:
6956                    return convert(new_name)
6957            else:
6958                try:
6959                    return convert(next(args))
6960                except StopIteration:
6961                    pass
6962        return node
6963
6964    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:
6967def expand(
6968    expression: Expression,
6969    sources: t.Dict[str, Query],
6970    dialect: DialectType = None,
6971    copy: bool = True,
6972) -> Expression:
6973    """Transforms an expression by expanding all referenced sources into subqueries.
6974
6975    Examples:
6976        >>> from sqlglot import parse_one
6977        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6978        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6979
6980        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6981        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6982
6983    Args:
6984        expression: The expression to expand.
6985        sources: A dictionary of name to Queries.
6986        dialect: The dialect of the sources dict.
6987        copy: Whether to copy the expression during transformation. Defaults to True.
6988
6989    Returns:
6990        The transformed expression.
6991    """
6992    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6993
6994    def _expand(node: Expression):
6995        if isinstance(node, Table):
6996            name = normalize_table_name(node, dialect=dialect)
6997            source = sources.get(name)
6998            if source:
6999                subquery = source.subquery(node.alias or name)
7000                subquery.comments = [f"source: {name}"]
7001                return subquery.transform(_expand, copy=False)
7002        return node
7003
7004    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:
7007def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7008    """
7009    Returns a Func expression.
7010
7011    Examples:
7012        >>> func("abs", 5).sql()
7013        'ABS(5)'
7014
7015        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7016        'CAST(5 AS DOUBLE)'
7017
7018    Args:
7019        name: the name of the function to build.
7020        args: the args used to instantiate the function of interest.
7021        copy: whether to copy the argument expressions.
7022        dialect: the source dialect.
7023        kwargs: the kwargs used to instantiate the function of interest.
7024
7025    Note:
7026        The arguments `args` and `kwargs` are mutually exclusive.
7027
7028    Returns:
7029        An instance of the function of interest, or an anonymous function, if `name` doesn't
7030        correspond to an existing `sqlglot.expressions.Func` class.
7031    """
7032    if args and kwargs:
7033        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7034
7035    from sqlglot.dialects.dialect import Dialect
7036
7037    dialect = Dialect.get_or_raise(dialect)
7038
7039    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7040    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7041
7042    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7043    if constructor:
7044        if converted:
7045            if "dialect" in constructor.__code__.co_varnames:
7046                function = constructor(converted, dialect=dialect)
7047            else:
7048                function = constructor(converted)
7049        elif constructor.__name__ == "from_arg_list":
7050            function = constructor.__self__(**kwargs)  # type: ignore
7051        else:
7052            constructor = FUNCTION_BY_NAME.get(name.upper())
7053            if constructor:
7054                function = constructor(**kwargs)
7055            else:
7056                raise ValueError(
7057                    f"Unable to convert '{name}' into a Func. Either manually construct "
7058                    "the Func expression of interest or parse the function call."
7059                )
7060    else:
7061        kwargs = kwargs or {"expressions": converted}
7062        function = Anonymous(this=name, **kwargs)
7063
7064    for error_message in function.error_messages(converted):
7065        raise ValueError(error_message)
7066
7067    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:
7070def case(
7071    expression: t.Optional[ExpOrStr] = None,
7072    **opts,
7073) -> Case:
7074    """
7075    Initialize a CASE statement.
7076
7077    Example:
7078        case().when("a = 1", "foo").else_("bar")
7079
7080    Args:
7081        expression: Optionally, the input expression (not all dialects support this)
7082        **opts: Extra keyword arguments for parsing `expression`
7083    """
7084    if expression is not None:
7085        this = maybe_parse(expression, **opts)
7086    else:
7087        this = None
7088    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:
7091def cast_unless(
7092    expression: ExpOrStr,
7093    to: DATA_TYPE,
7094    *types: DATA_TYPE,
7095    **opts: t.Any,
7096) -> Expression | Cast:
7097    """
7098    Cast an expression to a data type unless it is a specified type.
7099
7100    Args:
7101        expression: The expression to cast.
7102        to: The data type to cast to.
7103        **types: The types to exclude from casting.
7104        **opts: Extra keyword arguments for parsing `expression`
7105    """
7106    expr = maybe_parse(expression, **opts)
7107    if expr.is_type(*types):
7108        return expr
7109    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:
7112def array(
7113    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7114) -> Array:
7115    """
7116    Returns an array.
7117
7118    Examples:
7119        >>> array(1, 'x').sql()
7120        'ARRAY(1, x)'
7121
7122    Args:
7123        expressions: the expressions to add to the array.
7124        copy: whether to copy the argument expressions.
7125        dialect: the source dialect.
7126        kwargs: the kwargs used to instantiate the function of interest.
7127
7128    Returns:
7129        An array expression.
7130    """
7131    return Array(
7132        expressions=[
7133            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7134            for expression in expressions
7135        ]
7136    )

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:
7139def tuple_(
7140    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7141) -> Tuple:
7142    """
7143    Returns an tuple.
7144
7145    Examples:
7146        >>> tuple_(1, 'x').sql()
7147        '(1, x)'
7148
7149    Args:
7150        expressions: the expressions to add to the tuple.
7151        copy: whether to copy the argument expressions.
7152        dialect: the source dialect.
7153        kwargs: the kwargs used to instantiate the function of interest.
7154
7155    Returns:
7156        A tuple expression.
7157    """
7158    return Tuple(
7159        expressions=[
7160            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7161            for expression in expressions
7162        ]
7163    )

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:
7166def true() -> Boolean:
7167    """
7168    Returns a true Boolean expression.
7169    """
7170    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7173def false() -> Boolean:
7174    """
7175    Returns a false Boolean expression.
7176    """
7177    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7180def null() -> Null:
7181    """
7182    Returns a Null expression.
7183    """
7184    return Null()

Returns a Null expression.