Edit on GitHub

Expressions

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

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


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

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

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

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

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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

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

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
293    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
294        if self.comments is None:
295            self.comments = []
296        if comments:
297            for comment in comments:
298                _, *meta = comment.split(SQLGLOT_META)
299                if meta:
300                    for kv in "".join(meta).split(","):
301                        k, *v = kv.split("=")
302                        value = v[0].strip() if v else True
303                        self.meta[k.strip()] = value
304                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
306    def append(self, arg_key: str, value: t.Any) -> None:
307        """
308        Appends value to arg_key if it's a list or sets it as a new list.
309
310        Args:
311            arg_key (str): name of the list expression arg
312            value (Any): value to append to the list
313        """
314        if type(self.args.get(arg_key)) is not list:
315            self.args[arg_key] = []
316        self.args[arg_key].append(value)
317        self._set_parent(arg_key, value)

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

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any) -> None:
319    def set(self, arg_key: str, value: t.Any) -> None:
320        """
321        Sets arg_key to value.
322
323        Args:
324            arg_key: name of the expression arg.
325            value: value to set the arg to.
326        """
327        if value is None:
328            self.args.pop(arg_key, None)
329            return
330
331        self.args[arg_key] = value
332        self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int
344    @property
345    def depth(self) -> int:
346        """
347        Returns the depth of this tree.
348        """
349        if self.parent:
350            return self.parent.depth + 1
351        return 0

Returns the depth of this tree.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
431    def walk(self, bfs=True, prune=None):
432        """
433        Returns a generator object which visits all nodes in this tree.
434
435        Args:
436            bfs (bool): if set to True the BFS traversal order will be applied,
437                otherwise the DFS traversal will be used instead.
438            prune ((node, parent, arg_key) -> bool): callable that returns True if
439                the generator should stop traversing this branch of the tree.
440
441        Returns:
442            the generator object.
443        """
444        if bfs:
445            yield from self.bfs(prune=prune)
446        else:
447            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):
449    def dfs(self, parent=None, key=None, prune=None):
450        """
451        Returns a generator object which visits all nodes in this tree in
452        the DFS (Depth-first) order.
453
454        Returns:
455            The generator object.
456        """
457        stack = [(self, parent or self.parent, key)]
458
459        while stack:
460            node, parent, key = stack.pop()
461
462            yield node, parent, key
463
464            if prune and prune(node, parent, key):
465                continue
466
467            for k, v in node.iter_expressions(reverse=True):
468                stack.append((v, node, k))

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):
470    def bfs(self, prune=None):
471        """
472        Returns a generator object which visits all nodes in this tree in
473        the BFS (Breadth-first) order.
474
475        Returns:
476            The generator object.
477        """
478        queue = deque([(self, self.parent, None)])
479
480        while queue:
481            item, parent, key = queue.popleft()
482
483            yield item, parent, key
484            if prune and prune(item, parent, key):
485                continue
486
487            for k, v in item.iter_expressions():
488                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):
490    def unnest(self):
491        """
492        Returns the first non parenthesis child or self.
493        """
494        expression = self
495        while type(expression) is Paren:
496            expression = expression.this
497        return expression

Returns the first non parenthesis child or self.

def unalias(self):
499    def unalias(self):
500        """
501        Returns the inner expression if this is an Alias.
502        """
503        if isinstance(self, Alias):
504            return self.this
505        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
507    def unnest_operands(self):
508        """
509        Returns unnested operands as a tuple.
510        """
511        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

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

Logical conditions like x AND y, or simply x

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

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

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

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

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

selects: List[Expression]
1003    @property
1004    def selects(self) -> t.List[Expression]:
1005        """Returns the query's projections."""
1006        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

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

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

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

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):
1230class Create(DDL):
1231    arg_types = {
1232        "with": False,
1233        "this": True,
1234        "kind": True,
1235        "expression": False,
1236        "exists": False,
1237        "properties": False,
1238        "replace": False,
1239        "unique": False,
1240        "indexes": False,
1241        "no_schema_binding": False,
1242        "begin": False,
1243        "end": False,
1244        "clone": False,
1245    }
1246
1247    @property
1248    def kind(self) -> t.Optional[str]:
1249        kind = self.args.get("kind")
1250        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]
1247    @property
1248    def kind(self) -> t.Optional[str]:
1249        kind = self.args.get("kind")
1250        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1253class SequenceProperties(Expression):
1254    arg_types = {
1255        "increment": False,
1256        "minvalue": False,
1257        "maxvalue": False,
1258        "cache": False,
1259        "start": False,
1260        "owned": False,
1261        "options": False,
1262    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1265class TruncateTable(Expression):
1266    arg_types = {
1267        "expressions": True,
1268        "is_database": False,
1269        "exists": False,
1270        "only": False,
1271        "cluster": False,
1272        "identity": False,
1273        "option": False,
1274        "partition": False,
1275    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1281class Clone(Expression):
1282    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1285class Describe(Expression):
1286    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):
1289class Kill(Expression):
1290    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1293class Pragma(Expression):
1294    pass
key = 'pragma'
class Set(Expression):
1297class Set(Expression):
1298    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1301class Heredoc(Expression):
1302    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1305class SetItem(Expression):
1306    arg_types = {
1307        "this": False,
1308        "expressions": False,
1309        "kind": False,
1310        "collate": False,  # MySQL SET NAMES statement
1311        "global": False,
1312    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1315class Show(Expression):
1316    arg_types = {
1317        "this": True,
1318        "history": False,
1319        "terse": False,
1320        "target": False,
1321        "offset": False,
1322        "starts_with": False,
1323        "limit": False,
1324        "from": False,
1325        "like": False,
1326        "where": False,
1327        "db": False,
1328        "scope": False,
1329        "scope_kind": False,
1330        "full": False,
1331        "mutex": False,
1332        "query": False,
1333        "channel": False,
1334        "global": False,
1335        "log": False,
1336        "position": False,
1337        "types": False,
1338    }
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):
1341class UserDefinedFunction(Expression):
1342    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1345class CharacterSet(Expression):
1346    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1349class With(Expression):
1350    arg_types = {"expressions": True, "recursive": False}
1351
1352    @property
1353    def recursive(self) -> bool:
1354        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1352    @property
1353    def recursive(self) -> bool:
1354        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1357class WithinGroup(Expression):
1358    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1363class CTE(DerivedTable):
1364    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1367class TableAlias(Expression):
1368    arg_types = {"this": False, "columns": False}
1369
1370    @property
1371    def columns(self):
1372        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1370    @property
1371    def columns(self):
1372        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1375class BitString(Condition):
1376    pass
key = 'bitstring'
class HexString(Condition):
1379class HexString(Condition):
1380    pass
key = 'hexstring'
class ByteString(Condition):
1383class ByteString(Condition):
1384    pass
key = 'bytestring'
class RawString(Condition):
1387class RawString(Condition):
1388    pass
key = 'rawstring'
class UnicodeString(Condition):
1391class UnicodeString(Condition):
1392    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1395class Column(Condition):
1396    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1397
1398    @property
1399    def table(self) -> str:
1400        return self.text("table")
1401
1402    @property
1403    def db(self) -> str:
1404        return self.text("db")
1405
1406    @property
1407    def catalog(self) -> str:
1408        return self.text("catalog")
1409
1410    @property
1411    def output_name(self) -> str:
1412        return self.name
1413
1414    @property
1415    def parts(self) -> t.List[Identifier]:
1416        """Return the parts of a column in order catalog, db, table, name."""
1417        return [
1418            t.cast(Identifier, self.args[part])
1419            for part in ("catalog", "db", "table", "this")
1420            if self.args.get(part)
1421        ]
1422
1423    def to_dot(self) -> Dot | Identifier:
1424        """Converts the column into a dot expression."""
1425        parts = self.parts
1426        parent = self.parent
1427
1428        while parent:
1429            if isinstance(parent, Dot):
1430                parts.append(parent.expression)
1431            parent = parent.parent
1432
1433        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
1398    @property
1399    def table(self) -> str:
1400        return self.text("table")
db: str
1402    @property
1403    def db(self) -> str:
1404        return self.text("db")
catalog: str
1406    @property
1407    def catalog(self) -> str:
1408        return self.text("catalog")
output_name: str
1410    @property
1411    def output_name(self) -> str:
1412        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]
1414    @property
1415    def parts(self) -> t.List[Identifier]:
1416        """Return the parts of a column in order catalog, db, table, name."""
1417        return [
1418            t.cast(Identifier, self.args[part])
1419            for part in ("catalog", "db", "table", "this")
1420            if self.args.get(part)
1421        ]

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

def to_dot(self) -> Dot | Identifier:
1423    def to_dot(self) -> Dot | Identifier:
1424        """Converts the column into a dot expression."""
1425        parts = self.parts
1426        parent = self.parent
1427
1428        while parent:
1429            if isinstance(parent, Dot):
1430                parts.append(parent.expression)
1431            parent = parent.parent
1432
1433        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1436class ColumnPosition(Expression):
1437    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1440class ColumnDef(Expression):
1441    arg_types = {
1442        "this": True,
1443        "kind": False,
1444        "constraints": False,
1445        "exists": False,
1446        "position": False,
1447    }
1448
1449    @property
1450    def constraints(self) -> t.List[ColumnConstraint]:
1451        return self.args.get("constraints") or []
1452
1453    @property
1454    def kind(self) -> t.Optional[DataType]:
1455        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1449    @property
1450    def constraints(self) -> t.List[ColumnConstraint]:
1451        return self.args.get("constraints") or []
kind: Optional[DataType]
1453    @property
1454    def kind(self) -> t.Optional[DataType]:
1455        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1458class AlterColumn(Expression):
1459    arg_types = {
1460        "this": True,
1461        "dtype": False,
1462        "collate": False,
1463        "using": False,
1464        "default": False,
1465        "drop": False,
1466        "comment": False,
1467    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1470class RenameColumn(Expression):
1471    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1474class RenameTable(Expression):
1475    pass
key = 'renametable'
class SwapTable(Expression):
1478class SwapTable(Expression):
1479    pass
key = 'swaptable'
class Comment(Expression):
1482class Comment(Expression):
1483    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):
1486class Comprehension(Expression):
1487    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):
1491class MergeTreeTTLAction(Expression):
1492    arg_types = {
1493        "this": True,
1494        "delete": False,
1495        "recompress": False,
1496        "to_disk": False,
1497        "to_volume": False,
1498    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1502class MergeTreeTTL(Expression):
1503    arg_types = {
1504        "expressions": True,
1505        "where": False,
1506        "group": False,
1507        "aggregates": False,
1508    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1512class IndexConstraintOption(Expression):
1513    arg_types = {
1514        "key_block_size": False,
1515        "using": False,
1516        "parser": False,
1517        "comment": False,
1518        "visible": False,
1519        "engine_attr": False,
1520        "secondary_engine_attr": False,
1521    }
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):
1524class ColumnConstraint(Expression):
1525    arg_types = {"this": False, "kind": True}
1526
1527    @property
1528    def kind(self) -> ColumnConstraintKind:
1529        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1527    @property
1528    def kind(self) -> ColumnConstraintKind:
1529        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1532class ColumnConstraintKind(Expression):
1533    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1536class AutoIncrementColumnConstraint(ColumnConstraintKind):
1537    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1540class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1541    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1544class CaseSpecificColumnConstraint(ColumnConstraintKind):
1545    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1548class CharacterSetColumnConstraint(ColumnConstraintKind):
1549    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1552class CheckColumnConstraint(ColumnConstraintKind):
1553    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1556class ClusteredColumnConstraint(ColumnConstraintKind):
1557    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1560class CollateColumnConstraint(ColumnConstraintKind):
1561    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1564class CommentColumnConstraint(ColumnConstraintKind):
1565    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1568class CompressColumnConstraint(ColumnConstraintKind):
1569    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1572class DateFormatColumnConstraint(ColumnConstraintKind):
1573    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1576class DefaultColumnConstraint(ColumnConstraintKind):
1577    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1580class EncodeColumnConstraint(ColumnConstraintKind):
1581    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1585class ExcludeColumnConstraint(ColumnConstraintKind):
1586    pass
key = 'excludecolumnconstraint'
class WithOperator(Expression):
1589class WithOperator(Expression):
1590    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1593class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1594    # this: True -> ALWAYS, this: False -> BY DEFAULT
1595    arg_types = {
1596        "this": False,
1597        "expression": False,
1598        "on_null": False,
1599        "start": False,
1600        "increment": False,
1601        "minvalue": False,
1602        "maxvalue": False,
1603        "cycle": False,
1604    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1607class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1608    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1612class IndexColumnConstraint(ColumnConstraintKind):
1613    arg_types = {
1614        "this": False,
1615        "schema": True,
1616        "kind": False,
1617        "index_type": False,
1618        "options": False,
1619    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1622class InlineLengthColumnConstraint(ColumnConstraintKind):
1623    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1626class NonClusteredColumnConstraint(ColumnConstraintKind):
1627    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1630class NotForReplicationColumnConstraint(ColumnConstraintKind):
1631    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1634class NotNullColumnConstraint(ColumnConstraintKind):
1635    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1639class OnUpdateColumnConstraint(ColumnConstraintKind):
1640    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1644class TransformColumnConstraint(ColumnConstraintKind):
1645    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1648class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1649    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1652class TitleColumnConstraint(ColumnConstraintKind):
1653    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1656class UniqueColumnConstraint(ColumnConstraintKind):
1657    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1660class UppercaseColumnConstraint(ColumnConstraintKind):
1661    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1664class PathColumnConstraint(ColumnConstraintKind):
1665    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1670class ComputedColumnConstraint(ColumnConstraintKind):
1671    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1674class Constraint(Expression):
1675    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1678class Delete(DML):
1679    arg_types = {
1680        "with": False,
1681        "this": False,
1682        "using": False,
1683        "where": False,
1684        "returning": False,
1685        "limit": False,
1686        "tables": False,  # Multiple-Table Syntax (MySQL)
1687    }
1688
1689    def delete(
1690        self,
1691        table: ExpOrStr,
1692        dialect: DialectType = None,
1693        copy: bool = True,
1694        **opts,
1695    ) -> Delete:
1696        """
1697        Create a DELETE expression or replace the table on an existing DELETE expression.
1698
1699        Example:
1700            >>> delete("tbl").sql()
1701            'DELETE FROM tbl'
1702
1703        Args:
1704            table: the table from which to delete.
1705            dialect: the dialect used to parse the input expression.
1706            copy: if `False`, modify this expression instance in-place.
1707            opts: other options to use to parse the input expressions.
1708
1709        Returns:
1710            Delete: the modified expression.
1711        """
1712        return _apply_builder(
1713            expression=table,
1714            instance=self,
1715            arg="this",
1716            dialect=dialect,
1717            into=Table,
1718            copy=copy,
1719            **opts,
1720        )
1721
1722    def where(
1723        self,
1724        *expressions: t.Optional[ExpOrStr],
1725        append: bool = True,
1726        dialect: DialectType = None,
1727        copy: bool = True,
1728        **opts,
1729    ) -> Delete:
1730        """
1731        Append to or set the WHERE expressions.
1732
1733        Example:
1734            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1735            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1736
1737        Args:
1738            *expressions: the SQL code strings to parse.
1739                If an `Expression` instance is passed, it will be used as-is.
1740                Multiple expressions are combined with an AND operator.
1741            append: if `True`, AND the new expressions to any existing expression.
1742                Otherwise, this resets the expression.
1743            dialect: the dialect used to parse the input expressions.
1744            copy: if `False`, modify this expression instance in-place.
1745            opts: other options to use to parse the input expressions.
1746
1747        Returns:
1748            Delete: the modified expression.
1749        """
1750        return _apply_conjunction_builder(
1751            *expressions,
1752            instance=self,
1753            arg="where",
1754            append=append,
1755            into=Where,
1756            dialect=dialect,
1757            copy=copy,
1758            **opts,
1759        )
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:
1689    def delete(
1690        self,
1691        table: ExpOrStr,
1692        dialect: DialectType = None,
1693        copy: bool = True,
1694        **opts,
1695    ) -> Delete:
1696        """
1697        Create a DELETE expression or replace the table on an existing DELETE expression.
1698
1699        Example:
1700            >>> delete("tbl").sql()
1701            'DELETE FROM tbl'
1702
1703        Args:
1704            table: the table from which to delete.
1705            dialect: the dialect used to parse the input expression.
1706            copy: if `False`, modify this expression instance in-place.
1707            opts: other options to use to parse the input expressions.
1708
1709        Returns:
1710            Delete: the modified expression.
1711        """
1712        return _apply_builder(
1713            expression=table,
1714            instance=self,
1715            arg="this",
1716            dialect=dialect,
1717            into=Table,
1718            copy=copy,
1719            **opts,
1720        )

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

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):
1762class Drop(Expression):
1763    arg_types = {
1764        "this": False,
1765        "kind": False,
1766        "exists": False,
1767        "temporary": False,
1768        "materialized": False,
1769        "cascade": False,
1770        "constraints": False,
1771        "purge": False,
1772    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1775class Filter(Expression):
1776    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1779class Check(Expression):
1780    pass
key = 'check'
class Connect(Expression):
1784class Connect(Expression):
1785    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1788class Prior(Expression):
1789    pass
key = 'prior'
class Directory(Expression):
1792class Directory(Expression):
1793    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1794    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1797class ForeignKey(Expression):
1798    arg_types = {
1799        "expressions": True,
1800        "reference": False,
1801        "delete": False,
1802        "update": False,
1803    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1806class ColumnPrefix(Expression):
1807    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1810class PrimaryKey(Expression):
1811    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1816class Into(Expression):
1817    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1820class From(Expression):
1821    @property
1822    def name(self) -> str:
1823        return self.this.name
1824
1825    @property
1826    def alias_or_name(self) -> str:
1827        return self.this.alias_or_name
name: str
1821    @property
1822    def name(self) -> str:
1823        return self.this.name
alias_or_name: str
1825    @property
1826    def alias_or_name(self) -> str:
1827        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1830class Having(Expression):
1831    pass
key = 'having'
class Hint(Expression):
1834class Hint(Expression):
1835    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1838class JoinHint(Expression):
1839    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1842class Identifier(Expression):
1843    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1844
1845    @property
1846    def quoted(self) -> bool:
1847        return bool(self.args.get("quoted"))
1848
1849    @property
1850    def hashable_args(self) -> t.Any:
1851        return (self.this, self.quoted)
1852
1853    @property
1854    def output_name(self) -> str:
1855        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1845    @property
1846    def quoted(self) -> bool:
1847        return bool(self.args.get("quoted"))
hashable_args: Any
1849    @property
1850    def hashable_args(self) -> t.Any:
1851        return (self.this, self.quoted)
output_name: str
1853    @property
1854    def output_name(self) -> str:
1855        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):
1859class Opclass(Expression):
1860    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1863class Index(Expression):
1864    arg_types = {
1865        "this": False,
1866        "table": False,
1867        "unique": False,
1868        "primary": False,
1869        "amp": False,  # teradata
1870        "params": False,
1871    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1874class IndexParameters(Expression):
1875    arg_types = {
1876        "using": False,
1877        "include": False,
1878        "columns": False,
1879        "with_storage": False,
1880        "partition_by": False,
1881        "tablespace": False,
1882        "where": False,
1883    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1886class Insert(DDL, DML):
1887    arg_types = {
1888        "hint": False,
1889        "with": False,
1890        "this": True,
1891        "expression": False,
1892        "conflict": False,
1893        "returning": False,
1894        "overwrite": False,
1895        "exists": False,
1896        "partition": False,
1897        "alternative": False,
1898        "where": False,
1899        "ignore": False,
1900        "by_name": False,
1901    }
1902
1903    def with_(
1904        self,
1905        alias: ExpOrStr,
1906        as_: ExpOrStr,
1907        recursive: t.Optional[bool] = None,
1908        append: bool = True,
1909        dialect: DialectType = None,
1910        copy: bool = True,
1911        **opts,
1912    ) -> Insert:
1913        """
1914        Append to or set the common table expressions.
1915
1916        Example:
1917            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1918            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1919
1920        Args:
1921            alias: the SQL code string to parse as the table name.
1922                If an `Expression` instance is passed, this is used as-is.
1923            as_: the SQL code string to parse as the table expression.
1924                If an `Expression` instance is passed, it will be used as-is.
1925            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1926            append: if `True`, add to any existing expressions.
1927                Otherwise, this resets the expressions.
1928            dialect: the dialect used to parse the input expression.
1929            copy: if `False`, modify this expression instance in-place.
1930            opts: other options to use to parse the input expressions.
1931
1932        Returns:
1933            The modified expression.
1934        """
1935        return _apply_cte_builder(
1936            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1937        )
arg_types = {'hint': False, 'with': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1903    def with_(
1904        self,
1905        alias: ExpOrStr,
1906        as_: ExpOrStr,
1907        recursive: t.Optional[bool] = None,
1908        append: bool = True,
1909        dialect: DialectType = None,
1910        copy: bool = True,
1911        **opts,
1912    ) -> Insert:
1913        """
1914        Append to or set the common table expressions.
1915
1916        Example:
1917            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1918            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1919
1920        Args:
1921            alias: the SQL code string to parse as the table name.
1922                If an `Expression` instance is passed, this is used as-is.
1923            as_: the SQL code string to parse as the table expression.
1924                If an `Expression` instance is passed, it will be used as-is.
1925            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1926            append: if `True`, add to any existing expressions.
1927                Otherwise, this resets the expressions.
1928            dialect: the dialect used to parse the input expression.
1929            copy: if `False`, modify this expression instance in-place.
1930            opts: other options to use to parse the input expressions.
1931
1932        Returns:
1933            The modified expression.
1934        """
1935        return _apply_cte_builder(
1936            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1937        )

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):
1940class OnConflict(Expression):
1941    arg_types = {
1942        "duplicate": False,
1943        "expressions": False,
1944        "action": False,
1945        "conflict_keys": False,
1946        "constraint": False,
1947    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1950class Returning(Expression):
1951    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1955class Introducer(Expression):
1956    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1960class National(Expression):
1961    pass
key = 'national'
class LoadData(Expression):
1964class LoadData(Expression):
1965    arg_types = {
1966        "this": True,
1967        "local": False,
1968        "overwrite": False,
1969        "inpath": True,
1970        "partition": False,
1971        "input_format": False,
1972        "serde": False,
1973    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1976class Partition(Expression):
1977    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
1980class PartitionRange(Expression):
1981    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
1984class Fetch(Expression):
1985    arg_types = {
1986        "direction": False,
1987        "count": False,
1988        "percent": False,
1989        "with_ties": False,
1990    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1993class Group(Expression):
1994    arg_types = {
1995        "expressions": False,
1996        "grouping_sets": False,
1997        "cube": False,
1998        "rollup": False,
1999        "totals": False,
2000        "all": False,
2001    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2004class Lambda(Expression):
2005    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2008class Limit(Expression):
2009    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):
2012class Literal(Condition):
2013    arg_types = {"this": True, "is_string": True}
2014
2015    @property
2016    def hashable_args(self) -> t.Any:
2017        return (self.this, self.args.get("is_string"))
2018
2019    @classmethod
2020    def number(cls, number) -> Literal:
2021        return cls(this=str(number), is_string=False)
2022
2023    @classmethod
2024    def string(cls, string) -> Literal:
2025        return cls(this=str(string), is_string=True)
2026
2027    @property
2028    def output_name(self) -> str:
2029        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2015    @property
2016    def hashable_args(self) -> t.Any:
2017        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2019    @classmethod
2020    def number(cls, number) -> Literal:
2021        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2023    @classmethod
2024    def string(cls, string) -> Literal:
2025        return cls(this=str(string), is_string=True)
output_name: str
2027    @property
2028    def output_name(self) -> str:
2029        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):
2032class Join(Expression):
2033    arg_types = {
2034        "this": True,
2035        "on": False,
2036        "side": False,
2037        "kind": False,
2038        "using": False,
2039        "method": False,
2040        "global": False,
2041        "hint": False,
2042    }
2043
2044    @property
2045    def method(self) -> str:
2046        return self.text("method").upper()
2047
2048    @property
2049    def kind(self) -> str:
2050        return self.text("kind").upper()
2051
2052    @property
2053    def side(self) -> str:
2054        return self.text("side").upper()
2055
2056    @property
2057    def hint(self) -> str:
2058        return self.text("hint").upper()
2059
2060    @property
2061    def alias_or_name(self) -> str:
2062        return self.this.alias_or_name
2063
2064    def on(
2065        self,
2066        *expressions: t.Optional[ExpOrStr],
2067        append: bool = True,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Join:
2072        """
2073        Append to or set the ON expressions.
2074
2075        Example:
2076            >>> import sqlglot
2077            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2078            'JOIN x ON y = 1'
2079
2080        Args:
2081            *expressions: the SQL code strings to parse.
2082                If an `Expression` instance is passed, it will be used as-is.
2083                Multiple expressions are combined with an AND operator.
2084            append: if `True`, AND the new expressions to any existing expression.
2085                Otherwise, this resets the expression.
2086            dialect: the dialect used to parse the input expressions.
2087            copy: if `False`, modify this expression instance in-place.
2088            opts: other options to use to parse the input expressions.
2089
2090        Returns:
2091            The modified Join expression.
2092        """
2093        join = _apply_conjunction_builder(
2094            *expressions,
2095            instance=self,
2096            arg="on",
2097            append=append,
2098            dialect=dialect,
2099            copy=copy,
2100            **opts,
2101        )
2102
2103        if join.kind == "CROSS":
2104            join.set("kind", None)
2105
2106        return join
2107
2108    def using(
2109        self,
2110        *expressions: t.Optional[ExpOrStr],
2111        append: bool = True,
2112        dialect: DialectType = None,
2113        copy: bool = True,
2114        **opts,
2115    ) -> Join:
2116        """
2117        Append to or set the USING expressions.
2118
2119        Example:
2120            >>> import sqlglot
2121            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2122            'JOIN x USING (foo, bla)'
2123
2124        Args:
2125            *expressions: the SQL code strings to parse.
2126                If an `Expression` instance is passed, it will be used as-is.
2127            append: if `True`, concatenate the new expressions to the existing "using" list.
2128                Otherwise, this resets the expression.
2129            dialect: the dialect used to parse the input expressions.
2130            copy: if `False`, modify this expression instance in-place.
2131            opts: other options to use to parse the input expressions.
2132
2133        Returns:
2134            The modified Join expression.
2135        """
2136        join = _apply_list_builder(
2137            *expressions,
2138            instance=self,
2139            arg="using",
2140            append=append,
2141            dialect=dialect,
2142            copy=copy,
2143            **opts,
2144        )
2145
2146        if join.kind == "CROSS":
2147            join.set("kind", None)
2148
2149        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2044    @property
2045    def method(self) -> str:
2046        return self.text("method").upper()
kind: str
2048    @property
2049    def kind(self) -> str:
2050        return self.text("kind").upper()
side: str
2052    @property
2053    def side(self) -> str:
2054        return self.text("side").upper()
hint: str
2056    @property
2057    def hint(self) -> str:
2058        return self.text("hint").upper()
alias_or_name: str
2060    @property
2061    def alias_or_name(self) -> str:
2062        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:
2064    def on(
2065        self,
2066        *expressions: t.Optional[ExpOrStr],
2067        append: bool = True,
2068        dialect: DialectType = None,
2069        copy: bool = True,
2070        **opts,
2071    ) -> Join:
2072        """
2073        Append to or set the ON expressions.
2074
2075        Example:
2076            >>> import sqlglot
2077            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2078            'JOIN x ON y = 1'
2079
2080        Args:
2081            *expressions: the SQL code strings to parse.
2082                If an `Expression` instance is passed, it will be used as-is.
2083                Multiple expressions are combined with an AND operator.
2084            append: if `True`, AND the new expressions to any existing expression.
2085                Otherwise, this resets the expression.
2086            dialect: the dialect used to parse the input expressions.
2087            copy: if `False`, modify this expression instance in-place.
2088            opts: other options to use to parse the input expressions.
2089
2090        Returns:
2091            The modified Join expression.
2092        """
2093        join = _apply_conjunction_builder(
2094            *expressions,
2095            instance=self,
2096            arg="on",
2097            append=append,
2098            dialect=dialect,
2099            copy=copy,
2100            **opts,
2101        )
2102
2103        if join.kind == "CROSS":
2104            join.set("kind", None)
2105
2106        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:
2108    def using(
2109        self,
2110        *expressions: t.Optional[ExpOrStr],
2111        append: bool = True,
2112        dialect: DialectType = None,
2113        copy: bool = True,
2114        **opts,
2115    ) -> Join:
2116        """
2117        Append to or set the USING expressions.
2118
2119        Example:
2120            >>> import sqlglot
2121            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2122            'JOIN x USING (foo, bla)'
2123
2124        Args:
2125            *expressions: the SQL code strings to parse.
2126                If an `Expression` instance is passed, it will be used as-is.
2127            append: if `True`, concatenate the new expressions to the existing "using" list.
2128                Otherwise, this resets the expression.
2129            dialect: the dialect used to parse the input expressions.
2130            copy: if `False`, modify this expression instance in-place.
2131            opts: other options to use to parse the input expressions.
2132
2133        Returns:
2134            The modified Join expression.
2135        """
2136        join = _apply_list_builder(
2137            *expressions,
2138            instance=self,
2139            arg="using",
2140            append=append,
2141            dialect=dialect,
2142            copy=copy,
2143            **opts,
2144        )
2145
2146        if join.kind == "CROSS":
2147            join.set("kind", None)
2148
2149        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):
2152class Lateral(UDTF):
2153    arg_types = {
2154        "this": True,
2155        "view": False,
2156        "outer": False,
2157        "alias": False,
2158        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2159    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2162class MatchRecognize(Expression):
2163    arg_types = {
2164        "partition_by": False,
2165        "order": False,
2166        "measures": False,
2167        "rows": False,
2168        "after": False,
2169        "pattern": False,
2170        "define": False,
2171        "alias": False,
2172    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2177class Final(Expression):
2178    pass
key = 'final'
class Offset(Expression):
2181class Offset(Expression):
2182    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2185class Order(Expression):
2186    arg_types = {
2187        "this": False,
2188        "expressions": True,
2189        "interpolate": False,
2190        "siblings": False,
2191    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2195class WithFill(Expression):
2196    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2201class Cluster(Order):
2202    pass
key = 'cluster'
class Distribute(Order):
2205class Distribute(Order):
2206    pass
key = 'distribute'
class Sort(Order):
2209class Sort(Order):
2210    pass
key = 'sort'
class Ordered(Expression):
2213class Ordered(Expression):
2214    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):
2217class Property(Expression):
2218    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2221class AlgorithmProperty(Property):
2222    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2225class AutoIncrementProperty(Property):
2226    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2230class AutoRefreshProperty(Property):
2231    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2234class BackupProperty(Property):
2235    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2238class BlockCompressionProperty(Property):
2239    arg_types = {
2240        "autotemp": False,
2241        "always": False,
2242        "default": False,
2243        "manual": False,
2244        "never": False,
2245    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2248class CharacterSetProperty(Property):
2249    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2252class ChecksumProperty(Property):
2253    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2256class CollateProperty(Property):
2257    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2260class CopyGrantsProperty(Property):
2261    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2264class DataBlocksizeProperty(Property):
2265    arg_types = {
2266        "size": False,
2267        "units": False,
2268        "minimum": False,
2269        "maximum": False,
2270        "default": False,
2271    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2274class DefinerProperty(Property):
2275    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2278class DistKeyProperty(Property):
2279    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2282class DistStyleProperty(Property):
2283    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2286class EngineProperty(Property):
2287    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2290class HeapProperty(Property):
2291    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2294class ToTableProperty(Property):
2295    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2298class ExecuteAsProperty(Property):
2299    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2302class ExternalProperty(Property):
2303    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2306class FallbackProperty(Property):
2307    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2310class FileFormatProperty(Property):
2311    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2314class FreespaceProperty(Property):
2315    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2318class GlobalProperty(Property):
2319    arg_types = {}
arg_types = {}
key = 'globalproperty'
class InheritsProperty(Property):
2322class InheritsProperty(Property):
2323    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2326class InputModelProperty(Property):
2327    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2330class OutputModelProperty(Property):
2331    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2334class IsolatedLoadingProperty(Property):
2335    arg_types = {
2336        "no": False,
2337        "concurrent": False,
2338        "for_all": False,
2339        "for_insert": False,
2340        "for_none": False,
2341    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2344class JournalProperty(Property):
2345    arg_types = {
2346        "no": False,
2347        "dual": False,
2348        "before": False,
2349        "local": False,
2350        "after": False,
2351    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2354class LanguageProperty(Property):
2355    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2359class ClusteredByProperty(Property):
2360    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2363class DictProperty(Property):
2364    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2367class DictSubProperty(Property):
2368    pass
key = 'dictsubproperty'
class DictRange(Property):
2371class DictRange(Property):
2372    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2377class OnCluster(Property):
2378    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2381class LikeProperty(Property):
2382    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2385class LocationProperty(Property):
2386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2389class LockProperty(Property):
2390    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2393class LockingProperty(Property):
2394    arg_types = {
2395        "this": False,
2396        "kind": True,
2397        "for_or_in": False,
2398        "lock_type": True,
2399        "override": False,
2400    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2403class LogProperty(Property):
2404    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2407class MaterializedProperty(Property):
2408    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2411class MergeBlockRatioProperty(Property):
2412    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):
2415class NoPrimaryIndexProperty(Property):
2416    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2419class OnProperty(Property):
2420    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2423class OnCommitProperty(Property):
2424    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2427class PartitionedByProperty(Property):
2428    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2432class PartitionBoundSpec(Expression):
2433    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2434    arg_types = {
2435        "this": False,
2436        "expression": False,
2437        "from_expressions": False,
2438        "to_expressions": False,
2439    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2442class PartitionedOfProperty(Property):
2443    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2444    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2447class RemoteWithConnectionModelProperty(Property):
2448    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2451class ReturnsProperty(Property):
2452    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2455class RowFormatProperty(Property):
2456    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2459class RowFormatDelimitedProperty(Property):
2460    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2461    arg_types = {
2462        "fields": False,
2463        "escaped": False,
2464        "collection_items": False,
2465        "map_keys": False,
2466        "lines": False,
2467        "null": False,
2468        "serde": False,
2469    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2472class RowFormatSerdeProperty(Property):
2473    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2477class QueryTransform(Expression):
2478    arg_types = {
2479        "expressions": True,
2480        "command_script": True,
2481        "schema": False,
2482        "row_format_before": False,
2483        "record_writer": False,
2484        "row_format_after": False,
2485        "record_reader": False,
2486    }
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):
2489class SampleProperty(Property):
2490    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2493class SchemaCommentProperty(Property):
2494    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2497class SerdeProperties(Property):
2498    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2501class SetProperty(Property):
2502    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2505class SharingProperty(Property):
2506    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2509class SetConfigProperty(Property):
2510    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2513class SettingsProperty(Property):
2514    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2517class SortKeyProperty(Property):
2518    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2521class SqlReadWriteProperty(Property):
2522    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2525class SqlSecurityProperty(Property):
2526    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2529class StabilityProperty(Property):
2530    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2533class TemporaryProperty(Property):
2534    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2537class TransformModelProperty(Property):
2538    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2541class TransientProperty(Property):
2542    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2545class UnloggedProperty(Property):
2546    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class VolatileProperty(Property):
2549class VolatileProperty(Property):
2550    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2553class WithDataProperty(Property):
2554    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2557class WithJournalTableProperty(Property):
2558    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2561class WithSystemVersioningProperty(Property):
2562    # this -> history table name, expression -> data consistency check
2563    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2566class Properties(Expression):
2567    arg_types = {"expressions": True}
2568
2569    NAME_TO_PROPERTY = {
2570        "ALGORITHM": AlgorithmProperty,
2571        "AUTO_INCREMENT": AutoIncrementProperty,
2572        "CHARACTER SET": CharacterSetProperty,
2573        "CLUSTERED_BY": ClusteredByProperty,
2574        "COLLATE": CollateProperty,
2575        "COMMENT": SchemaCommentProperty,
2576        "DEFINER": DefinerProperty,
2577        "DISTKEY": DistKeyProperty,
2578        "DISTSTYLE": DistStyleProperty,
2579        "ENGINE": EngineProperty,
2580        "EXECUTE AS": ExecuteAsProperty,
2581        "FORMAT": FileFormatProperty,
2582        "LANGUAGE": LanguageProperty,
2583        "LOCATION": LocationProperty,
2584        "LOCK": LockProperty,
2585        "PARTITIONED_BY": PartitionedByProperty,
2586        "RETURNS": ReturnsProperty,
2587        "ROW_FORMAT": RowFormatProperty,
2588        "SORTKEY": SortKeyProperty,
2589    }
2590
2591    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2592
2593    # CREATE property locations
2594    # Form: schema specified
2595    #   create [POST_CREATE]
2596    #     table a [POST_NAME]
2597    #     (b int) [POST_SCHEMA]
2598    #     with ([POST_WITH])
2599    #     index (b) [POST_INDEX]
2600    #
2601    # Form: alias selection
2602    #   create [POST_CREATE]
2603    #     table a [POST_NAME]
2604    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2605    #     index (c) [POST_INDEX]
2606    class Location(AutoName):
2607        POST_CREATE = auto()
2608        POST_NAME = auto()
2609        POST_SCHEMA = auto()
2610        POST_WITH = auto()
2611        POST_ALIAS = auto()
2612        POST_EXPRESSION = auto()
2613        POST_INDEX = auto()
2614        UNSUPPORTED = auto()
2615
2616    @classmethod
2617    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2618        expressions = []
2619        for key, value in properties_dict.items():
2620            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2621            if property_cls:
2622                expressions.append(property_cls(this=convert(value)))
2623            else:
2624                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2625
2626        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:
2616    @classmethod
2617    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2618        expressions = []
2619        for key, value in properties_dict.items():
2620            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2621            if property_cls:
2622                expressions.append(property_cls(this=convert(value)))
2623            else:
2624                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2625
2626        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2606    class Location(AutoName):
2607        POST_CREATE = auto()
2608        POST_NAME = auto()
2609        POST_SCHEMA = auto()
2610        POST_WITH = auto()
2611        POST_ALIAS = auto()
2612        POST_EXPRESSION = auto()
2613        POST_INDEX = auto()
2614        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):
2629class Qualify(Expression):
2630    pass
key = 'qualify'
class InputOutputFormat(Expression):
2633class InputOutputFormat(Expression):
2634    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2638class Return(Expression):
2639    pass
key = 'return'
class Reference(Expression):
2642class Reference(Expression):
2643    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2646class Tuple(Expression):
2647    arg_types = {"expressions": False}
2648
2649    def isin(
2650        self,
2651        *expressions: t.Any,
2652        query: t.Optional[ExpOrStr] = None,
2653        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2654        copy: bool = True,
2655        **opts,
2656    ) -> In:
2657        return In(
2658            this=maybe_copy(self, copy),
2659            expressions=[convert(e, copy=copy) for e in expressions],
2660            query=maybe_parse(query, copy=copy, **opts) if query else None,
2661            unnest=(
2662                Unnest(
2663                    expressions=[
2664                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2665                        for e in ensure_list(unnest)
2666                    ]
2667                )
2668                if unnest
2669                else None
2670            ),
2671        )
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:
2649    def isin(
2650        self,
2651        *expressions: t.Any,
2652        query: t.Optional[ExpOrStr] = None,
2653        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2654        copy: bool = True,
2655        **opts,
2656    ) -> In:
2657        return In(
2658            this=maybe_copy(self, copy),
2659            expressions=[convert(e, copy=copy) for e in expressions],
2660            query=maybe_parse(query, copy=copy, **opts) if query else None,
2661            unnest=(
2662                Unnest(
2663                    expressions=[
2664                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2665                        for e in ensure_list(unnest)
2666                    ]
2667                )
2668                if unnest
2669                else None
2670            ),
2671        )
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):
2702class QueryOption(Expression):
2703    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2707class WithTableHint(Expression):
2708    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2712class IndexTableHint(Expression):
2713    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2717class HistoricalData(Expression):
2718    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2721class Table(Expression):
2722    arg_types = {
2723        "this": False,
2724        "alias": False,
2725        "db": False,
2726        "catalog": False,
2727        "laterals": False,
2728        "joins": False,
2729        "pivots": False,
2730        "hints": False,
2731        "system_time": False,
2732        "version": False,
2733        "format": False,
2734        "pattern": False,
2735        "ordinality": False,
2736        "when": False,
2737        "only": False,
2738    }
2739
2740    @property
2741    def name(self) -> str:
2742        if isinstance(self.this, Func):
2743            return ""
2744        return self.this.name
2745
2746    @property
2747    def db(self) -> str:
2748        return self.text("db")
2749
2750    @property
2751    def catalog(self) -> str:
2752        return self.text("catalog")
2753
2754    @property
2755    def selects(self) -> t.List[Expression]:
2756        return []
2757
2758    @property
2759    def named_selects(self) -> t.List[str]:
2760        return []
2761
2762    @property
2763    def parts(self) -> t.List[Expression]:
2764        """Return the parts of a table in order catalog, db, table."""
2765        parts: t.List[Expression] = []
2766
2767        for arg in ("catalog", "db", "this"):
2768            part = self.args.get(arg)
2769
2770            if isinstance(part, Dot):
2771                parts.extend(part.flatten())
2772            elif isinstance(part, Expression):
2773                parts.append(part)
2774
2775        return parts
2776
2777    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2778        parts = self.parts
2779        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2780        alias = self.args.get("alias")
2781        if alias:
2782            col = alias_(col, alias.this, copy=copy)
2783        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
2740    @property
2741    def name(self) -> str:
2742        if isinstance(self.this, Func):
2743            return ""
2744        return self.this.name
db: str
2746    @property
2747    def db(self) -> str:
2748        return self.text("db")
catalog: str
2750    @property
2751    def catalog(self) -> str:
2752        return self.text("catalog")
selects: List[Expression]
2754    @property
2755    def selects(self) -> t.List[Expression]:
2756        return []
named_selects: List[str]
2758    @property
2759    def named_selects(self) -> t.List[str]:
2760        return []
parts: List[Expression]
2762    @property
2763    def parts(self) -> t.List[Expression]:
2764        """Return the parts of a table in order catalog, db, table."""
2765        parts: t.List[Expression] = []
2766
2767        for arg in ("catalog", "db", "this"):
2768            part = self.args.get(arg)
2769
2770            if isinstance(part, Dot):
2771                parts.extend(part.flatten())
2772            elif isinstance(part, Expression):
2773                parts.append(part)
2774
2775        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2777    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2778        parts = self.parts
2779        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2780        alias = self.args.get("alias")
2781        if alias:
2782            col = alias_(col, alias.this, copy=copy)
2783        return col
key = 'table'
class Union(Query):
2786class Union(Query):
2787    arg_types = {
2788        "with": False,
2789        "this": True,
2790        "expression": True,
2791        "distinct": False,
2792        "by_name": False,
2793        **QUERY_MODIFIERS,
2794    }
2795
2796    def select(
2797        self,
2798        *expressions: t.Optional[ExpOrStr],
2799        append: bool = True,
2800        dialect: DialectType = None,
2801        copy: bool = True,
2802        **opts,
2803    ) -> Union:
2804        this = maybe_copy(self, copy)
2805        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2806        this.expression.unnest().select(
2807            *expressions, append=append, dialect=dialect, copy=False, **opts
2808        )
2809        return this
2810
2811    @property
2812    def named_selects(self) -> t.List[str]:
2813        return self.this.unnest().named_selects
2814
2815    @property
2816    def is_star(self) -> bool:
2817        return self.this.is_star or self.expression.is_star
2818
2819    @property
2820    def selects(self) -> t.List[Expression]:
2821        return self.this.unnest().selects
2822
2823    @property
2824    def left(self) -> Expression:
2825        return self.this
2826
2827    @property
2828    def right(self) -> Expression:
2829        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:
2796    def select(
2797        self,
2798        *expressions: t.Optional[ExpOrStr],
2799        append: bool = True,
2800        dialect: DialectType = None,
2801        copy: bool = True,
2802        **opts,
2803    ) -> Union:
2804        this = maybe_copy(self, copy)
2805        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2806        this.expression.unnest().select(
2807            *expressions, append=append, dialect=dialect, copy=False, **opts
2808        )
2809        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]
2811    @property
2812    def named_selects(self) -> t.List[str]:
2813        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2815    @property
2816    def is_star(self) -> bool:
2817        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2819    @property
2820    def selects(self) -> t.List[Expression]:
2821        return self.this.unnest().selects

Returns the query's projections.

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

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:
2945    def group_by(
2946        self,
2947        *expressions: t.Optional[ExpOrStr],
2948        append: bool = True,
2949        dialect: DialectType = None,
2950        copy: bool = True,
2951        **opts,
2952    ) -> Select:
2953        """
2954        Set the GROUP BY expression.
2955
2956        Example:
2957            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2958            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2959
2960        Args:
2961            *expressions: the SQL code strings to parse.
2962                If a `Group` instance is passed, this is used as-is.
2963                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2964                If nothing is passed in then a group by is not applied to the expression
2965            append: if `True`, add to any existing expressions.
2966                Otherwise, this flattens all the `Group` expression into a single expression.
2967            dialect: the dialect used to parse the input expression.
2968            copy: if `False`, modify this expression instance in-place.
2969            opts: other options to use to parse the input expressions.
2970
2971        Returns:
2972            The modified Select expression.
2973        """
2974        if not expressions:
2975            return self if not copy else self.copy()
2976
2977        return _apply_child_list_builder(
2978            *expressions,
2979            instance=self,
2980            arg="group",
2981            append=append,
2982            copy=copy,
2983            prefix="GROUP BY",
2984            into=Group,
2985            dialect=dialect,
2986            **opts,
2987        )

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

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:
3029    def sort_by(
3030        self,
3031        *expressions: t.Optional[ExpOrStr],
3032        append: bool = True,
3033        dialect: DialectType = None,
3034        copy: bool = True,
3035        **opts,
3036    ) -> Select:
3037        """
3038        Set the SORT BY expression.
3039
3040        Example:
3041            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3042            'SELECT x FROM tbl SORT BY x DESC'
3043
3044        Args:
3045            *expressions: the SQL code strings to parse.
3046                If a `Group` instance is passed, this is used as-is.
3047                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3048            append: if `True`, add to any existing expressions.
3049                Otherwise, this flattens all the `Order` expression into a single expression.
3050            dialect: the dialect used to parse the input expression.
3051            copy: if `False`, modify this expression instance in-place.
3052            opts: other options to use to parse the input expressions.
3053
3054        Returns:
3055            The modified Select expression.
3056        """
3057        return _apply_child_list_builder(
3058            *expressions,
3059            instance=self,
3060            arg="sort",
3061            append=append,
3062            copy=copy,
3063            prefix="SORT BY",
3064            into=Sort,
3065            dialect=dialect,
3066            **opts,
3067        )

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:
3069    def cluster_by(
3070        self,
3071        *expressions: t.Optional[ExpOrStr],
3072        append: bool = True,
3073        dialect: DialectType = None,
3074        copy: bool = True,
3075        **opts,
3076    ) -> Select:
3077        """
3078        Set the CLUSTER BY expression.
3079
3080        Example:
3081            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3082            'SELECT x FROM tbl CLUSTER BY x DESC'
3083
3084        Args:
3085            *expressions: the SQL code strings to parse.
3086                If a `Group` instance is passed, this is used as-is.
3087                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3088            append: if `True`, add to any existing expressions.
3089                Otherwise, this flattens all the `Order` expression into a single expression.
3090            dialect: the dialect used to parse the input expression.
3091            copy: if `False`, modify this expression instance in-place.
3092            opts: other options to use to parse the input expressions.
3093
3094        Returns:
3095            The modified Select expression.
3096        """
3097        return _apply_child_list_builder(
3098            *expressions,
3099            instance=self,
3100            arg="cluster",
3101            append=append,
3102            copy=copy,
3103            prefix="CLUSTER BY",
3104            into=Cluster,
3105            dialect=dialect,
3106            **opts,
3107        )

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:
3109    def limit(
3110        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3111    ) -> Select:
3112        return _apply_builder(
3113            expression=expression,
3114            instance=self,
3115            arg="limit",
3116            into=Limit,
3117            prefix="LIMIT",
3118            dialect=dialect,
3119            copy=copy,
3120            into_arg="expression",
3121            **opts,
3122        )

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:
3124    def offset(
3125        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3126    ) -> Select:
3127        """
3128        Set the OFFSET expression.
3129
3130        Example:
3131            >>> Select().from_("tbl").select("x").offset(10).sql()
3132            'SELECT x FROM tbl OFFSET 10'
3133
3134        Args:
3135            expression: the SQL code string to parse.
3136                This can also be an integer.
3137                If a `Offset` instance is passed, this is used as-is.
3138                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3139            dialect: the dialect used to parse the input expression.
3140            copy: if `False`, modify this expression instance in-place.
3141            opts: other options to use to parse the input expressions.
3142
3143        Returns:
3144            The modified Select expression.
3145        """
3146        return _apply_builder(
3147            expression=expression,
3148            instance=self,
3149            arg="offset",
3150            into=Offset,
3151            prefix="OFFSET",
3152            dialect=dialect,
3153            copy=copy,
3154            into_arg="expression",
3155            **opts,
3156        )

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:
3158    def select(
3159        self,
3160        *expressions: t.Optional[ExpOrStr],
3161        append: bool = True,
3162        dialect: DialectType = None,
3163        copy: bool = True,
3164        **opts,
3165    ) -> Select:
3166        return _apply_list_builder(
3167            *expressions,
3168            instance=self,
3169            arg="expressions",
3170            append=append,
3171            dialect=dialect,
3172            into=Expression,
3173            copy=copy,
3174            **opts,
3175        )

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:
3177    def lateral(
3178        self,
3179        *expressions: t.Optional[ExpOrStr],
3180        append: bool = True,
3181        dialect: DialectType = None,
3182        copy: bool = True,
3183        **opts,
3184    ) -> Select:
3185        """
3186        Append to or set the LATERAL expressions.
3187
3188        Example:
3189            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3190            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3191
3192        Args:
3193            *expressions: the SQL code strings to parse.
3194                If an `Expression` instance is passed, it will be used as-is.
3195            append: if `True`, add to any existing expressions.
3196                Otherwise, this resets the expressions.
3197            dialect: the dialect used to parse the input expressions.
3198            copy: if `False`, modify this expression instance in-place.
3199            opts: other options to use to parse the input expressions.
3200
3201        Returns:
3202            The modified Select expression.
3203        """
3204        return _apply_list_builder(
3205            *expressions,
3206            instance=self,
3207            arg="laterals",
3208            append=append,
3209            into=Lateral,
3210            prefix="LATERAL VIEW",
3211            dialect=dialect,
3212            copy=copy,
3213            **opts,
3214        )

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

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:
3314    def where(
3315        self,
3316        *expressions: t.Optional[ExpOrStr],
3317        append: bool = True,
3318        dialect: DialectType = None,
3319        copy: bool = True,
3320        **opts,
3321    ) -> Select:
3322        """
3323        Append to or set the WHERE expressions.
3324
3325        Example:
3326            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3327            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3328
3329        Args:
3330            *expressions: the SQL code strings to parse.
3331                If an `Expression` instance is passed, it will be used as-is.
3332                Multiple expressions are combined with an AND operator.
3333            append: if `True`, AND the new expressions to any existing expression.
3334                Otherwise, this resets the expression.
3335            dialect: the dialect used to parse the input expressions.
3336            copy: if `False`, modify this expression instance in-place.
3337            opts: other options to use to parse the input expressions.
3338
3339        Returns:
3340            Select: the modified expression.
3341        """
3342        return _apply_conjunction_builder(
3343            *expressions,
3344            instance=self,
3345            arg="where",
3346            append=append,
3347            into=Where,
3348            dialect=dialect,
3349            copy=copy,
3350            **opts,
3351        )

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:
3353    def having(
3354        self,
3355        *expressions: t.Optional[ExpOrStr],
3356        append: bool = True,
3357        dialect: DialectType = None,
3358        copy: bool = True,
3359        **opts,
3360    ) -> Select:
3361        """
3362        Append to or set the HAVING expressions.
3363
3364        Example:
3365            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3366            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3367
3368        Args:
3369            *expressions: the SQL code strings to parse.
3370                If an `Expression` instance is passed, it will be used as-is.
3371                Multiple expressions are combined with an AND operator.
3372            append: if `True`, AND the new expressions to any existing expression.
3373                Otherwise, this resets the expression.
3374            dialect: the dialect used to parse the input expressions.
3375            copy: if `False`, modify this expression instance in-place.
3376            opts: other options to use to parse the input expressions.
3377
3378        Returns:
3379            The modified Select expression.
3380        """
3381        return _apply_conjunction_builder(
3382            *expressions,
3383            instance=self,
3384            arg="having",
3385            append=append,
3386            into=Having,
3387            dialect=dialect,
3388            copy=copy,
3389            **opts,
3390        )

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:
3392    def window(
3393        self,
3394        *expressions: t.Optional[ExpOrStr],
3395        append: bool = True,
3396        dialect: DialectType = None,
3397        copy: bool = True,
3398        **opts,
3399    ) -> Select:
3400        return _apply_list_builder(
3401            *expressions,
3402            instance=self,
3403            arg="windows",
3404            append=append,
3405            into=Window,
3406            dialect=dialect,
3407            copy=copy,
3408            **opts,
3409        )
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:
3411    def qualify(
3412        self,
3413        *expressions: t.Optional[ExpOrStr],
3414        append: bool = True,
3415        dialect: DialectType = None,
3416        copy: bool = True,
3417        **opts,
3418    ) -> Select:
3419        return _apply_conjunction_builder(
3420            *expressions,
3421            instance=self,
3422            arg="qualify",
3423            append=append,
3424            into=Qualify,
3425            dialect=dialect,
3426            copy=copy,
3427            **opts,
3428        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3430    def distinct(
3431        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3432    ) -> Select:
3433        """
3434        Set the OFFSET expression.
3435
3436        Example:
3437            >>> Select().from_("tbl").select("x").distinct().sql()
3438            'SELECT DISTINCT x FROM tbl'
3439
3440        Args:
3441            ons: the expressions to distinct on
3442            distinct: whether the Select should be distinct
3443            copy: if `False`, modify this expression instance in-place.
3444
3445        Returns:
3446            Select: the modified expression.
3447        """
3448        instance = maybe_copy(self, copy)
3449        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3450        instance.set("distinct", Distinct(on=on) if distinct else None)
3451        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:
3453    def ctas(
3454        self,
3455        table: ExpOrStr,
3456        properties: t.Optional[t.Dict] = None,
3457        dialect: DialectType = None,
3458        copy: bool = True,
3459        **opts,
3460    ) -> Create:
3461        """
3462        Convert this expression to a CREATE TABLE AS statement.
3463
3464        Example:
3465            >>> Select().select("*").from_("tbl").ctas("x").sql()
3466            'CREATE TABLE x AS SELECT * FROM tbl'
3467
3468        Args:
3469            table: the SQL code string to parse as the table name.
3470                If another `Expression` instance is passed, it will be used as-is.
3471            properties: an optional mapping of table properties
3472            dialect: the dialect used to parse the input table.
3473            copy: if `False`, modify this expression instance in-place.
3474            opts: other options to use to parse the input table.
3475
3476        Returns:
3477            The new Create expression.
3478        """
3479        instance = maybe_copy(self, copy)
3480        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3481
3482        properties_expression = None
3483        if properties:
3484            properties_expression = Properties.from_dict(properties)
3485
3486        return Create(
3487            this=table_expression,
3488            kind="TABLE",
3489            expression=instance,
3490            properties=properties_expression,
3491        )

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:
3493    def lock(self, update: bool = True, copy: bool = True) -> Select:
3494        """
3495        Set the locking read mode for this expression.
3496
3497        Examples:
3498            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3499            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3500
3501            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3502            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3503
3504        Args:
3505            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3506            copy: if `False`, modify this expression instance in-place.
3507
3508        Returns:
3509            The modified expression.
3510        """
3511        inst = maybe_copy(self, copy)
3512        inst.set("locks", [Lock(update=update)])
3513
3514        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:
3516    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3517        """
3518        Set hints for this expression.
3519
3520        Examples:
3521            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3522            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3523
3524        Args:
3525            hints: The SQL code strings to parse as the hints.
3526                If an `Expression` instance is passed, it will be used as-is.
3527            dialect: The dialect used to parse the hints.
3528            copy: If `False`, modify this expression instance in-place.
3529
3530        Returns:
3531            The modified expression.
3532        """
3533        inst = maybe_copy(self, copy)
3534        inst.set(
3535            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3536        )
3537
3538        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]
3540    @property
3541    def named_selects(self) -> t.List[str]:
3542        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
3544    @property
3545    def is_star(self) -> bool:
3546        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3548    @property
3549    def selects(self) -> t.List[Expression]:
3550        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3556class Subquery(DerivedTable, Query):
3557    arg_types = {
3558        "this": True,
3559        "alias": False,
3560        "with": False,
3561        **QUERY_MODIFIERS,
3562    }
3563
3564    def unnest(self):
3565        """Returns the first non subquery."""
3566        expression = self
3567        while isinstance(expression, Subquery):
3568            expression = expression.this
3569        return expression
3570
3571    def unwrap(self) -> Subquery:
3572        expression = self
3573        while expression.same_parent and expression.is_wrapper:
3574            expression = t.cast(Subquery, expression.parent)
3575        return expression
3576
3577    def select(
3578        self,
3579        *expressions: t.Optional[ExpOrStr],
3580        append: bool = True,
3581        dialect: DialectType = None,
3582        copy: bool = True,
3583        **opts,
3584    ) -> Subquery:
3585        this = maybe_copy(self, copy)
3586        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3587        return this
3588
3589    @property
3590    def is_wrapper(self) -> bool:
3591        """
3592        Whether this Subquery acts as a simple wrapper around another expression.
3593
3594        SELECT * FROM (((SELECT * FROM t)))
3595                      ^
3596                      This corresponds to a "wrapper" Subquery node
3597        """
3598        return all(v is None for k, v in self.args.items() if k != "this")
3599
3600    @property
3601    def is_star(self) -> bool:
3602        return self.this.is_star
3603
3604    @property
3605    def output_name(self) -> str:
3606        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):
3564    def unnest(self):
3565        """Returns the first non subquery."""
3566        expression = self
3567        while isinstance(expression, Subquery):
3568            expression = expression.this
3569        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3571    def unwrap(self) -> Subquery:
3572        expression = self
3573        while expression.same_parent and expression.is_wrapper:
3574            expression = t.cast(Subquery, expression.parent)
3575        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:
3577    def select(
3578        self,
3579        *expressions: t.Optional[ExpOrStr],
3580        append: bool = True,
3581        dialect: DialectType = None,
3582        copy: bool = True,
3583        **opts,
3584    ) -> Subquery:
3585        this = maybe_copy(self, copy)
3586        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3587        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
3589    @property
3590    def is_wrapper(self) -> bool:
3591        """
3592        Whether this Subquery acts as a simple wrapper around another expression.
3593
3594        SELECT * FROM (((SELECT * FROM t)))
3595                      ^
3596                      This corresponds to a "wrapper" Subquery node
3597        """
3598        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
3600    @property
3601    def is_star(self) -> bool:
3602        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3604    @property
3605    def output_name(self) -> str:
3606        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):
3609class TableSample(Expression):
3610    arg_types = {
3611        "this": False,
3612        "expressions": False,
3613        "method": False,
3614        "bucket_numerator": False,
3615        "bucket_denominator": False,
3616        "bucket_field": False,
3617        "percent": False,
3618        "rows": False,
3619        "size": False,
3620        "seed": False,
3621    }
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):
3624class Tag(Expression):
3625    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3626
3627    arg_types = {
3628        "this": False,
3629        "prefix": False,
3630        "postfix": False,
3631    }

Tags are used for generating arbitrary sql like SELECT x.

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

Checks whether an expression is a star.

name: str
4105    @property
4106    def name(self) -> str:
4107        return self.expression.name
output_name: str
4109    @property
4110    def output_name(self) -> str:
4111        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:
4113    @classmethod
4114    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4115        """Build a Dot object with a sequence of expressions."""
4116        if len(expressions) < 2:
4117            raise ValueError("Dot requires >= 2 expressions.")
4118
4119        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]
4121    @property
4122    def parts(self) -> t.List[Expression]:
4123        """Return the parts of a table / column in order catalog, db, table."""
4124        this, *parts = self.flatten()
4125
4126        parts.reverse()
4127
4128        for arg in ("this", "table", "db", "catalog"):
4129            part = this.args.get(arg)
4130
4131            if isinstance(part, Expression):
4132                parts.append(part)
4133
4134        parts.reverse()
4135        return parts

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

key = 'dot'
class DPipe(Binary):
4138class DPipe(Binary):
4139    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4142class EQ(Binary, Predicate):
4143    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4146class NullSafeEQ(Binary, Predicate):
4147    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4150class NullSafeNEQ(Binary, Predicate):
4151    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4155class PropertyEQ(Binary):
4156    pass
key = 'propertyeq'
class Distance(Binary):
4159class Distance(Binary):
4160    pass
key = 'distance'
class Escape(Binary):
4163class Escape(Binary):
4164    pass
key = 'escape'
class Glob(Binary, Predicate):
4167class Glob(Binary, Predicate):
4168    pass
key = 'glob'
class GT(Binary, Predicate):
4171class GT(Binary, Predicate):
4172    pass
key = 'gt'
class GTE(Binary, Predicate):
4175class GTE(Binary, Predicate):
4176    pass
key = 'gte'
class ILike(Binary, Predicate):
4179class ILike(Binary, Predicate):
4180    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4183class ILikeAny(Binary, Predicate):
4184    pass
key = 'ilikeany'
class IntDiv(Binary):
4187class IntDiv(Binary):
4188    pass
key = 'intdiv'
class Is(Binary, Predicate):
4191class Is(Binary, Predicate):
4192    pass
key = 'is'
class Kwarg(Binary):
4195class Kwarg(Binary):
4196    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4199class Like(Binary, Predicate):
4200    pass
key = 'like'
class LikeAny(Binary, Predicate):
4203class LikeAny(Binary, Predicate):
4204    pass
key = 'likeany'
class LT(Binary, Predicate):
4207class LT(Binary, Predicate):
4208    pass
key = 'lt'
class LTE(Binary, Predicate):
4211class LTE(Binary, Predicate):
4212    pass
key = 'lte'
class Mod(Binary):
4215class Mod(Binary):
4216    pass
key = 'mod'
class Mul(Binary):
4219class Mul(Binary):
4220    pass
key = 'mul'
class NEQ(Binary, Predicate):
4223class NEQ(Binary, Predicate):
4224    pass
key = 'neq'
class Operator(Binary):
4228class Operator(Binary):
4229    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4232class SimilarTo(Binary, Predicate):
4233    pass
key = 'similarto'
class Slice(Binary):
4236class Slice(Binary):
4237    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4240class Sub(Binary):
4241    pass
key = 'sub'
class Unary(Condition):
4246class Unary(Condition):
4247    pass
key = 'unary'
class BitwiseNot(Unary):
4250class BitwiseNot(Unary):
4251    pass
key = 'bitwisenot'
class Not(Unary):
4254class Not(Unary):
4255    pass
key = 'not'
class Paren(Unary):
4258class Paren(Unary):
4259    arg_types = {"this": True, "with": False}
4260
4261    @property
4262    def output_name(self) -> str:
4263        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4261    @property
4262    def output_name(self) -> str:
4263        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):
4266class Neg(Unary):
4267    pass
key = 'neg'
class Alias(Expression):
4270class Alias(Expression):
4271    arg_types = {"this": True, "alias": False}
4272
4273    @property
4274    def output_name(self) -> str:
4275        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4273    @property
4274    def output_name(self) -> str:
4275        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):
4280class PivotAlias(Alias):
4281    pass
key = 'pivotalias'
class Aliases(Expression):
4284class Aliases(Expression):
4285    arg_types = {"this": True, "expressions": True}
4286
4287    @property
4288    def aliases(self):
4289        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4287    @property
4288    def aliases(self):
4289        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4293class AtIndex(Expression):
4294    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4297class AtTimeZone(Expression):
4298    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4301class FromTimeZone(Expression):
4302    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4305class Between(Predicate):
4306    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4309class Bracket(Condition):
4310    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4311    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4312
4313    @property
4314    def output_name(self) -> str:
4315        if len(self.expressions) == 1:
4316            return self.expressions[0].output_name
4317
4318        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4313    @property
4314    def output_name(self) -> str:
4315        if len(self.expressions) == 1:
4316            return self.expressions[0].output_name
4317
4318        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):
4321class Distinct(Expression):
4322    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4325class In(Predicate):
4326    arg_types = {
4327        "this": True,
4328        "expressions": False,
4329        "query": False,
4330        "unnest": False,
4331        "field": False,
4332        "is_global": False,
4333    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4337class ForIn(Expression):
4338    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4341class TimeUnit(Expression):
4342    """Automatically converts unit arg into a var."""
4343
4344    arg_types = {"unit": False}
4345
4346    UNABBREVIATED_UNIT_NAME = {
4347        "D": "DAY",
4348        "H": "HOUR",
4349        "M": "MINUTE",
4350        "MS": "MILLISECOND",
4351        "NS": "NANOSECOND",
4352        "Q": "QUARTER",
4353        "S": "SECOND",
4354        "US": "MICROSECOND",
4355        "W": "WEEK",
4356        "Y": "YEAR",
4357    }
4358
4359    VAR_LIKE = (Column, Literal, Var)
4360
4361    def __init__(self, **args):
4362        unit = args.get("unit")
4363        if isinstance(unit, self.VAR_LIKE):
4364            args["unit"] = Var(
4365                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4366            )
4367        elif isinstance(unit, Week):
4368            unit.set("this", Var(this=unit.this.name.upper()))
4369
4370        super().__init__(**args)
4371
4372    @property
4373    def unit(self) -> t.Optional[Var]:
4374        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4361    def __init__(self, **args):
4362        unit = args.get("unit")
4363        if isinstance(unit, self.VAR_LIKE):
4364            args["unit"] = Var(
4365                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4366            )
4367        elif isinstance(unit, Week):
4368            unit.set("this", Var(this=unit.this.name.upper()))
4369
4370        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]
4372    @property
4373    def unit(self) -> t.Optional[Var]:
4374        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4377class IntervalOp(TimeUnit):
4378    arg_types = {"unit": True, "expression": True}
4379
4380    def interval(self):
4381        return Interval(
4382            this=self.expression.copy(),
4383            unit=self.unit.copy(),
4384        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4380    def interval(self):
4381        return Interval(
4382            this=self.expression.copy(),
4383            unit=self.unit.copy(),
4384        )
key = 'intervalop'
class IntervalSpan(DataType):
4390class IntervalSpan(DataType):
4391    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4394class Interval(TimeUnit):
4395    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4398class IgnoreNulls(Expression):
4399    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4402class RespectNulls(Expression):
4403    pass
key = 'respectnulls'
class HavingMax(Expression):
4407class HavingMax(Expression):
4408    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4412class Func(Condition):
4413    """
4414    The base class for all function expressions.
4415
4416    Attributes:
4417        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4418            treated as a variable length argument and the argument's value will be stored as a list.
4419        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4420            function expression. These values are used to map this node to a name during parsing as
4421            well as to provide the function's name during SQL string generation. By default the SQL
4422            name is set to the expression's class name transformed to snake case.
4423    """
4424
4425    is_var_len_args = False
4426
4427    @classmethod
4428    def from_arg_list(cls, args):
4429        if cls.is_var_len_args:
4430            all_arg_keys = list(cls.arg_types)
4431            # If this function supports variable length argument treat the last argument as such.
4432            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4433            num_non_var = len(non_var_len_arg_keys)
4434
4435            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4436            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4437        else:
4438            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4439
4440        return cls(**args_dict)
4441
4442    @classmethod
4443    def sql_names(cls):
4444        if cls is Func:
4445            raise NotImplementedError(
4446                "SQL name is only supported by concrete function implementations"
4447            )
4448        if "_sql_names" not in cls.__dict__:
4449            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4450        return cls._sql_names
4451
4452    @classmethod
4453    def sql_name(cls):
4454        return cls.sql_names()[0]
4455
4456    @classmethod
4457    def default_parser_mappings(cls):
4458        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):
4427    @classmethod
4428    def from_arg_list(cls, args):
4429        if cls.is_var_len_args:
4430            all_arg_keys = list(cls.arg_types)
4431            # If this function supports variable length argument treat the last argument as such.
4432            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4433            num_non_var = len(non_var_len_arg_keys)
4434
4435            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4436            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4437        else:
4438            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4439
4440        return cls(**args_dict)
@classmethod
def sql_names(cls):
4442    @classmethod
4443    def sql_names(cls):
4444        if cls is Func:
4445            raise NotImplementedError(
4446                "SQL name is only supported by concrete function implementations"
4447            )
4448        if "_sql_names" not in cls.__dict__:
4449            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4450        return cls._sql_names
@classmethod
def sql_name(cls):
4452    @classmethod
4453    def sql_name(cls):
4454        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4456    @classmethod
4457    def default_parser_mappings(cls):
4458        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4461class AggFunc(Func):
4462    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4465class ParameterizedAgg(AggFunc):
4466    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4469class Abs(Func):
4470    pass
key = 'abs'
class ArgMax(AggFunc):
4473class ArgMax(AggFunc):
4474    arg_types = {"this": True, "expression": True, "count": False}
4475    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4478class ArgMin(AggFunc):
4479    arg_types = {"this": True, "expression": True, "count": False}
4480    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4483class ApproxTopK(AggFunc):
4484    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4487class Flatten(Func):
4488    pass
key = 'flatten'
class Transform(Func):
4492class Transform(Func):
4493    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4496class Anonymous(Func):
4497    arg_types = {"this": True, "expressions": False}
4498    is_var_len_args = True
4499
4500    @property
4501    def name(self) -> str:
4502        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4500    @property
4501    def name(self) -> str:
4502        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4505class AnonymousAggFunc(AggFunc):
4506    arg_types = {"this": True, "expressions": False}
4507    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4511class CombinedAggFunc(AnonymousAggFunc):
4512    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4515class CombinedParameterizedAgg(ParameterizedAgg):
4516    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):
4521class Hll(AggFunc):
4522    arg_types = {"this": True, "expressions": False}
4523    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4526class ApproxDistinct(AggFunc):
4527    arg_types = {"this": True, "accuracy": False}
4528    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4531class Array(Func):
4532    arg_types = {"expressions": False}
4533    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4537class ToArray(Func):
4538    pass
key = 'toarray'
class ToChar(Func):
4543class ToChar(Func):
4544    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4549class ToNumber(Func):
4550    arg_types = {
4551        "this": True,
4552        "format": False,
4553        "nlsparam": False,
4554        "precision": False,
4555        "scale": False,
4556    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4560class Convert(Func):
4561    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4564class GenerateSeries(Func):
4565    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):
4568class ArrayAgg(AggFunc):
4569    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4572class ArrayUniqueAgg(AggFunc):
4573    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4576class ArrayAll(Func):
4577    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4581class ArrayAny(Func):
4582    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4585class ArrayConcat(Func):
4586    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4587    arg_types = {"this": True, "expressions": False}
4588    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4591class ArrayContains(Binary, Func):
4592    pass
key = 'arraycontains'
class ArrayContained(Binary):
4595class ArrayContained(Binary):
4596    pass
key = 'arraycontained'
class ArrayFilter(Func):
4599class ArrayFilter(Func):
4600    arg_types = {"this": True, "expression": True}
4601    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4604class ArrayToString(Func):
4605    arg_types = {"this": True, "expression": True, "null": False}
4606    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4609class ArrayOverlaps(Binary, Func):
4610    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4613class ArraySize(Func):
4614    arg_types = {"this": True, "expression": False}
4615    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4618class ArraySort(Func):
4619    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4622class ArraySum(Func):
4623    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4626class ArrayUnionAgg(AggFunc):
4627    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4630class Avg(AggFunc):
4631    pass
key = 'avg'
class AnyValue(AggFunc):
4634class AnyValue(AggFunc):
4635    pass
key = 'anyvalue'
class Lag(AggFunc):
4638class Lag(AggFunc):
4639    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4642class Lead(AggFunc):
4643    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4648class First(AggFunc):
4649    pass
key = 'first'
class Last(AggFunc):
4652class Last(AggFunc):
4653    pass
key = 'last'
class FirstValue(AggFunc):
4656class FirstValue(AggFunc):
4657    pass
key = 'firstvalue'
class LastValue(AggFunc):
4660class LastValue(AggFunc):
4661    pass
key = 'lastvalue'
class NthValue(AggFunc):
4664class NthValue(AggFunc):
4665    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4668class Case(Func):
4669    arg_types = {"this": False, "ifs": True, "default": False}
4670
4671    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4672        instance = maybe_copy(self, copy)
4673        instance.append(
4674            "ifs",
4675            If(
4676                this=maybe_parse(condition, copy=copy, **opts),
4677                true=maybe_parse(then, copy=copy, **opts),
4678            ),
4679        )
4680        return instance
4681
4682    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4683        instance = maybe_copy(self, copy)
4684        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4685        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:
4671    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4672        instance = maybe_copy(self, copy)
4673        instance.append(
4674            "ifs",
4675            If(
4676                this=maybe_parse(condition, copy=copy, **opts),
4677                true=maybe_parse(then, copy=copy, **opts),
4678            ),
4679        )
4680        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4682    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4683        instance = maybe_copy(self, copy)
4684        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4685        return instance
key = 'case'
class Cast(Func):
4688class Cast(Func):
4689    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4690
4691    @property
4692    def name(self) -> str:
4693        return self.this.name
4694
4695    @property
4696    def to(self) -> DataType:
4697        return self.args["to"]
4698
4699    @property
4700    def output_name(self) -> str:
4701        return self.name
4702
4703    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4704        """
4705        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4706        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4707        array<int> != array<float>.
4708
4709        Args:
4710            dtypes: the data types to compare this Cast's DataType to.
4711
4712        Returns:
4713            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4714        """
4715        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4691    @property
4692    def name(self) -> str:
4693        return self.this.name
to: DataType
4695    @property
4696    def to(self) -> DataType:
4697        return self.args["to"]
output_name: str
4699    @property
4700    def output_name(self) -> str:
4701        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:
4703    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4704        """
4705        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4706        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4707        array<int> != array<float>.
4708
4709        Args:
4710            dtypes: the data types to compare this Cast's DataType to.
4711
4712        Returns:
4713            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4714        """
4715        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):
4718class TryCast(Cast):
4719    pass
key = 'trycast'
class CastToStrType(Func):
4722class CastToStrType(Func):
4723    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4726class Collate(Binary, Func):
4727    pass
key = 'collate'
class Ceil(Func):
4730class Ceil(Func):
4731    arg_types = {"this": True, "decimals": False}
4732    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4735class Coalesce(Func):
4736    arg_types = {"this": True, "expressions": False}
4737    is_var_len_args = True
4738    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4741class Chr(Func):
4742    arg_types = {"this": True, "charset": False, "expressions": False}
4743    is_var_len_args = True
4744    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4747class Concat(Func):
4748    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4749    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4752class ConcatWs(Concat):
4753    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4757class ConnectByRoot(Func):
4758    pass
key = 'connectbyroot'
class Count(AggFunc):
4761class Count(AggFunc):
4762    arg_types = {"this": False, "expressions": False}
4763    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4766class CountIf(AggFunc):
4767    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4771class Cbrt(Func):
4772    pass
key = 'cbrt'
class CurrentDate(Func):
4775class CurrentDate(Func):
4776    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4779class CurrentDatetime(Func):
4780    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4783class CurrentTime(Func):
4784    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4787class CurrentTimestamp(Func):
4788    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4791class CurrentUser(Func):
4792    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4795class DateAdd(Func, IntervalOp):
4796    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4799class DateSub(Func, IntervalOp):
4800    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4803class DateDiff(Func, TimeUnit):
4804    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4805    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4808class DateTrunc(Func):
4809    arg_types = {"unit": True, "this": True, "zone": False}
4810
4811    def __init__(self, **args):
4812        unit = args.get("unit")
4813        if isinstance(unit, TimeUnit.VAR_LIKE):
4814            args["unit"] = Literal.string(
4815                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4816            )
4817        elif isinstance(unit, Week):
4818            unit.set("this", Literal.string(unit.this.name.upper()))
4819
4820        super().__init__(**args)
4821
4822    @property
4823    def unit(self) -> Expression:
4824        return self.args["unit"]
DateTrunc(**args)
4811    def __init__(self, **args):
4812        unit = args.get("unit")
4813        if isinstance(unit, TimeUnit.VAR_LIKE):
4814            args["unit"] = Literal.string(
4815                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4816            )
4817        elif isinstance(unit, Week):
4818            unit.set("this", Literal.string(unit.this.name.upper()))
4819
4820        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4822    @property
4823    def unit(self) -> Expression:
4824        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4827class DatetimeAdd(Func, IntervalOp):
4828    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4831class DatetimeSub(Func, IntervalOp):
4832    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4835class DatetimeDiff(Func, TimeUnit):
4836    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4839class DatetimeTrunc(Func, TimeUnit):
4840    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4843class DayOfWeek(Func):
4844    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4847class DayOfMonth(Func):
4848    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4851class DayOfYear(Func):
4852    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4855class ToDays(Func):
4856    pass
key = 'todays'
class WeekOfYear(Func):
4859class WeekOfYear(Func):
4860    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4863class MonthsBetween(Func):
4864    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4867class LastDay(Func, TimeUnit):
4868    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4869    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4872class Extract(Func):
4873    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4876class Timestamp(Func):
4877    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4880class TimestampAdd(Func, TimeUnit):
4881    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4884class TimestampSub(Func, TimeUnit):
4885    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4888class TimestampDiff(Func, TimeUnit):
4889    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4890    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4893class TimestampTrunc(Func, TimeUnit):
4894    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4897class TimeAdd(Func, TimeUnit):
4898    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4901class TimeSub(Func, TimeUnit):
4902    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4905class TimeDiff(Func, TimeUnit):
4906    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4909class TimeTrunc(Func, TimeUnit):
4910    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4913class DateFromParts(Func):
4914    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4915    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4918class TimeFromParts(Func):
4919    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4920    arg_types = {
4921        "hour": True,
4922        "min": True,
4923        "sec": True,
4924        "nano": False,
4925        "fractions": False,
4926        "precision": False,
4927    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4930class DateStrToDate(Func):
4931    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4934class DateToDateStr(Func):
4935    pass
key = 'datetodatestr'
class DateToDi(Func):
4938class DateToDi(Func):
4939    pass
key = 'datetodi'
class Date(Func):
4943class Date(Func):
4944    arg_types = {"this": False, "zone": False, "expressions": False}
4945    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4948class Day(Func):
4949    pass
key = 'day'
class Decode(Func):
4952class Decode(Func):
4953    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4956class DiToDate(Func):
4957    pass
key = 'ditodate'
class Encode(Func):
4960class Encode(Func):
4961    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4964class Exp(Func):
4965    pass
key = 'exp'
class Explode(Func):
4969class Explode(Func):
4970    arg_types = {"this": True, "expressions": False}
4971    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4974class ExplodeOuter(Explode):
4975    pass
key = 'explodeouter'
class Posexplode(Explode):
4978class Posexplode(Explode):
4979    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4982class PosexplodeOuter(Posexplode, ExplodeOuter):
4983    pass
key = 'posexplodeouter'
class Floor(Func):
4986class Floor(Func):
4987    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4990class FromBase64(Func):
4991    pass
key = 'frombase64'
class ToBase64(Func):
4994class ToBase64(Func):
4995    pass
key = 'tobase64'
class Greatest(Func):
4998class Greatest(Func):
4999    arg_types = {"this": True, "expressions": False}
5000    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5003class GroupConcat(AggFunc):
5004    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5007class Hex(Func):
5008    pass
key = 'hex'
class Xor(Connector, Func):
5011class Xor(Connector, Func):
5012    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5015class If(Func):
5016    arg_types = {"this": True, "true": True, "false": False}
5017    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5020class Nullif(Func):
5021    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5024class Initcap(Func):
5025    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5028class IsNan(Func):
5029    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5032class IsInf(Func):
5033    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5036class JSONPath(Expression):
5037    arg_types = {"expressions": True}
5038
5039    @property
5040    def output_name(self) -> str:
5041        last_segment = self.expressions[-1].this
5042        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5039    @property
5040    def output_name(self) -> str:
5041        last_segment = self.expressions[-1].this
5042        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):
5045class JSONPathPart(Expression):
5046    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5049class JSONPathFilter(JSONPathPart):
5050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5053class JSONPathKey(JSONPathPart):
5054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5057class JSONPathRecursive(JSONPathPart):
5058    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5061class JSONPathRoot(JSONPathPart):
5062    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5065class JSONPathScript(JSONPathPart):
5066    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5069class JSONPathSlice(JSONPathPart):
5070    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5073class JSONPathSelector(JSONPathPart):
5074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5077class JSONPathSubscript(JSONPathPart):
5078    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5081class JSONPathUnion(JSONPathPart):
5082    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5085class JSONPathWildcard(JSONPathPart):
5086    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5089class FormatJson(Expression):
5090    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5093class JSONKeyValue(Expression):
5094    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5097class JSONObject(Func):
5098    arg_types = {
5099        "expressions": False,
5100        "null_handling": False,
5101        "unique_keys": False,
5102        "return_type": False,
5103        "encoding": False,
5104    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5107class JSONObjectAgg(AggFunc):
5108    arg_types = {
5109        "expressions": False,
5110        "null_handling": False,
5111        "unique_keys": False,
5112        "return_type": False,
5113        "encoding": False,
5114    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5118class JSONArray(Func):
5119    arg_types = {
5120        "expressions": True,
5121        "null_handling": False,
5122        "return_type": False,
5123        "strict": False,
5124    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5128class JSONArrayAgg(Func):
5129    arg_types = {
5130        "this": True,
5131        "order": False,
5132        "null_handling": False,
5133        "return_type": False,
5134        "strict": False,
5135    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5140class JSONColumnDef(Expression):
5141    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):
5144class JSONSchema(Expression):
5145    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5149class JSONTable(Func):
5150    arg_types = {
5151        "this": True,
5152        "schema": True,
5153        "path": False,
5154        "error_handling": False,
5155        "empty_handling": False,
5156    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5159class OpenJSONColumnDef(Expression):
5160    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):
5163class OpenJSON(Func):
5164    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5167class JSONBContains(Binary):
5168    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5171class JSONExtract(Binary, Func):
5172    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5173    _sql_names = ["JSON_EXTRACT"]
5174    is_var_len_args = True
5175
5176    @property
5177    def output_name(self) -> str:
5178        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
5176    @property
5177    def output_name(self) -> str:
5178        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):
5181class JSONExtractScalar(Binary, Func):
5182    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5183    _sql_names = ["JSON_EXTRACT_SCALAR"]
5184    is_var_len_args = True
5185
5186    @property
5187    def output_name(self) -> str:
5188        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
5186    @property
5187    def output_name(self) -> str:
5188        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):
5191class JSONBExtract(Binary, Func):
5192    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5195class JSONBExtractScalar(Binary, Func):
5196    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5199class JSONFormat(Func):
5200    arg_types = {"this": False, "options": False}
5201    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5205class JSONArrayContains(Binary, Predicate, Func):
5206    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5209class ParseJSON(Func):
5210    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5211    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5212    arg_types = {"this": True, "expressions": False}
5213    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5216class Least(Func):
5217    arg_types = {"this": True, "expressions": False}
5218    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5221class Left(Func):
5222    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5229class Length(Func):
5230    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5233class Levenshtein(Func):
5234    arg_types = {
5235        "this": True,
5236        "expression": False,
5237        "ins_cost": False,
5238        "del_cost": False,
5239        "sub_cost": False,
5240    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5243class Ln(Func):
5244    pass
key = 'ln'
class Log(Func):
5247class Log(Func):
5248    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5251class Log2(Func):
5252    pass
key = 'log2'
class Log10(Func):
5255class Log10(Func):
5256    pass
key = 'log10'
class LogicalOr(AggFunc):
5259class LogicalOr(AggFunc):
5260    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5263class LogicalAnd(AggFunc):
5264    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5267class Lower(Func):
5268    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5271class Map(Func):
5272    arg_types = {"keys": False, "values": False}
5273
5274    @property
5275    def keys(self) -> t.List[Expression]:
5276        keys = self.args.get("keys")
5277        return keys.expressions if keys else []
5278
5279    @property
5280    def values(self) -> t.List[Expression]:
5281        values = self.args.get("values")
5282        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5274    @property
5275    def keys(self) -> t.List[Expression]:
5276        keys = self.args.get("keys")
5277        return keys.expressions if keys else []
values: List[Expression]
5279    @property
5280    def values(self) -> t.List[Expression]:
5281        values = self.args.get("values")
5282        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5285class MapFromEntries(Func):
5286    pass
key = 'mapfromentries'
class StarMap(Func):
5289class StarMap(Func):
5290    pass
key = 'starmap'
class VarMap(Func):
5293class VarMap(Func):
5294    arg_types = {"keys": True, "values": True}
5295    is_var_len_args = True
5296
5297    @property
5298    def keys(self) -> t.List[Expression]:
5299        return self.args["keys"].expressions
5300
5301    @property
5302    def values(self) -> t.List[Expression]:
5303        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5297    @property
5298    def keys(self) -> t.List[Expression]:
5299        return self.args["keys"].expressions
values: List[Expression]
5301    @property
5302    def values(self) -> t.List[Expression]:
5303        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5307class MatchAgainst(Func):
5308    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5311class Max(AggFunc):
5312    arg_types = {"this": True, "expressions": False}
5313    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5316class MD5(Func):
5317    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5321class MD5Digest(Func):
5322    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5325class Min(AggFunc):
5326    arg_types = {"this": True, "expressions": False}
5327    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5330class Month(Func):
5331    pass
key = 'month'
class AddMonths(Func):
5334class AddMonths(Func):
5335    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5338class Nvl2(Func):
5339    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5343class Predict(Func):
5344    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5347class Pow(Binary, Func):
5348    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5351class PercentileCont(AggFunc):
5352    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5355class PercentileDisc(AggFunc):
5356    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5359class Quantile(AggFunc):
5360    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5363class ApproxQuantile(Quantile):
5364    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):
5367class Rand(Func):
5368    _sql_names = ["RAND", "RANDOM"]
5369    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5372class Randn(Func):
5373    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5376class RangeN(Func):
5377    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5380class ReadCSV(Func):
5381    _sql_names = ["READ_CSV"]
5382    is_var_len_args = True
5383    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5386class Reduce(Func):
5387    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):
5390class RegexpExtract(Func):
5391    arg_types = {
5392        "this": True,
5393        "expression": True,
5394        "position": False,
5395        "occurrence": False,
5396        "parameters": False,
5397        "group": False,
5398    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5401class RegexpReplace(Func):
5402    arg_types = {
5403        "this": True,
5404        "expression": True,
5405        "replacement": False,
5406        "position": False,
5407        "occurrence": False,
5408        "parameters": False,
5409        "modifiers": False,
5410    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5413class RegexpLike(Binary, Func):
5414    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5417class RegexpILike(Binary, Func):
5418    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5423class RegexpSplit(Func):
5424    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5427class Repeat(Func):
5428    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5433class Round(Func):
5434    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5437class RowNumber(Func):
5438    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5441class SafeDivide(Func):
5442    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5445class SHA(Func):
5446    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5449class SHA2(Func):
5450    _sql_names = ["SHA2"]
5451    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5454class Sign(Func):
5455    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5458class SortArray(Func):
5459    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5462class Split(Func):
5463    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5468class Substring(Func):
5469    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5472class StandardHash(Func):
5473    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5476class StartsWith(Func):
5477    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5478    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5481class StrPosition(Func):
5482    arg_types = {
5483        "this": True,
5484        "substr": True,
5485        "position": False,
5486        "instance": False,
5487    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5490class StrToDate(Func):
5491    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5494class StrToTime(Func):
5495    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5500class StrToUnix(Func):
5501    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5506class StrToMap(Func):
5507    arg_types = {
5508        "this": True,
5509        "pair_delim": False,
5510        "key_value_delim": False,
5511        "duplicate_resolution_callback": False,
5512    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5515class NumberToStr(Func):
5516    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5519class FromBase(Func):
5520    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5523class Struct(Func):
5524    arg_types = {"expressions": False}
5525    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5528class StructExtract(Func):
5529    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5534class Stuff(Func):
5535    _sql_names = ["STUFF", "INSERT"]
5536    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):
5539class Sum(AggFunc):
5540    pass
key = 'sum'
class Sqrt(Func):
5543class Sqrt(Func):
5544    pass
key = 'sqrt'
class Stddev(AggFunc):
5547class Stddev(AggFunc):
5548    pass
key = 'stddev'
class StddevPop(AggFunc):
5551class StddevPop(AggFunc):
5552    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5555class StddevSamp(AggFunc):
5556    pass
key = 'stddevsamp'
class TimeToStr(Func):
5559class TimeToStr(Func):
5560    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5563class TimeToTimeStr(Func):
5564    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5567class TimeToUnix(Func):
5568    pass
key = 'timetounix'
class TimeStrToDate(Func):
5571class TimeStrToDate(Func):
5572    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5575class TimeStrToTime(Func):
5576    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5579class TimeStrToUnix(Func):
5580    pass
key = 'timestrtounix'
class Trim(Func):
5583class Trim(Func):
5584    arg_types = {
5585        "this": True,
5586        "expression": False,
5587        "position": False,
5588        "collation": False,
5589    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5592class TsOrDsAdd(Func, TimeUnit):
5593    # return_type is used to correctly cast the arguments of this expression when transpiling it
5594    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5595
5596    @property
5597    def return_type(self) -> DataType:
5598        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
5596    @property
5597    def return_type(self) -> DataType:
5598        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5601class TsOrDsDiff(Func, TimeUnit):
5602    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5605class TsOrDsToDateStr(Func):
5606    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5609class TsOrDsToDate(Func):
5610    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5613class TsOrDsToTime(Func):
5614    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5617class TsOrDiToDi(Func):
5618    pass
key = 'tsorditodi'
class Unhex(Func):
5621class Unhex(Func):
5622    pass
key = 'unhex'
class UnixDate(Func):
5626class UnixDate(Func):
5627    pass
key = 'unixdate'
class UnixToStr(Func):
5630class UnixToStr(Func):
5631    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5636class UnixToTime(Func):
5637    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5638
5639    SECONDS = Literal.number(0)
5640    DECIS = Literal.number(1)
5641    CENTIS = Literal.number(2)
5642    MILLIS = Literal.number(3)
5643    DECIMILLIS = Literal.number(4)
5644    CENTIMILLIS = Literal.number(5)
5645    MICROS = Literal.number(6)
5646    DECIMICROS = Literal.number(7)
5647    CENTIMICROS = Literal.number(8)
5648    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):
5651class UnixToTimeStr(Func):
5652    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5655class TimestampFromParts(Func):
5656    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5657    arg_types = {
5658        "year": True,
5659        "month": True,
5660        "day": True,
5661        "hour": True,
5662        "min": True,
5663        "sec": True,
5664        "nano": False,
5665        "zone": False,
5666        "milli": False,
5667    }
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):
5670class Upper(Func):
5671    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5674class Variance(AggFunc):
5675    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5678class VariancePop(AggFunc):
5679    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5682class Week(Func):
5683    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5686class XMLTable(Func):
5687    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):
5690class Year(Func):
5691    pass
key = 'year'
class Use(Expression):
5694class Use(Expression):
5695    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5698class Merge(Expression):
5699    arg_types = {
5700        "this": True,
5701        "using": True,
5702        "on": True,
5703        "expressions": True,
5704        "with": False,
5705    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5708class When(Func):
5709    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):
5714class NextValueFor(Func):
5715    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 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToNumber'>, <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_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_NUMBER': <class 'ToNumber'>, '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:
5753def maybe_parse(
5754    sql_or_expression: ExpOrStr,
5755    *,
5756    into: t.Optional[IntoType] = None,
5757    dialect: DialectType = None,
5758    prefix: t.Optional[str] = None,
5759    copy: bool = False,
5760    **opts,
5761) -> Expression:
5762    """Gracefully handle a possible string or expression.
5763
5764    Example:
5765        >>> maybe_parse("1")
5766        Literal(this=1, is_string=False)
5767        >>> maybe_parse(to_identifier("x"))
5768        Identifier(this=x, quoted=False)
5769
5770    Args:
5771        sql_or_expression: the SQL code string or an expression
5772        into: the SQLGlot Expression to parse into
5773        dialect: the dialect used to parse the input expressions (in the case that an
5774            input expression is a SQL string).
5775        prefix: a string to prefix the sql with before it gets parsed
5776            (automatically includes a space)
5777        copy: whether to copy the expression.
5778        **opts: other options to use to parse the input expressions (again, in the case
5779            that an input expression is a SQL string).
5780
5781    Returns:
5782        Expression: the parsed or given expression.
5783    """
5784    if isinstance(sql_or_expression, Expression):
5785        if copy:
5786            return sql_or_expression.copy()
5787        return sql_or_expression
5788
5789    if sql_or_expression is None:
5790        raise ParseError("SQL cannot be None")
5791
5792    import sqlglot
5793
5794    sql = str(sql_or_expression)
5795    if prefix:
5796        sql = f"{prefix} {sql}"
5797
5798    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):
5809def maybe_copy(instance, copy=True):
5810    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:
6024def union(
6025    left: ExpOrStr,
6026    right: ExpOrStr,
6027    distinct: bool = True,
6028    dialect: DialectType = None,
6029    copy: bool = True,
6030    **opts,
6031) -> Union:
6032    """
6033    Initializes a syntax tree from one UNION expression.
6034
6035    Example:
6036        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6037        'SELECT * FROM foo UNION SELECT * FROM bla'
6038
6039    Args:
6040        left: the SQL code string corresponding to the left-hand side.
6041            If an `Expression` instance is passed, it will be used as-is.
6042        right: the SQL code string corresponding to the right-hand side.
6043            If an `Expression` instance is passed, it will be used as-is.
6044        distinct: set the DISTINCT flag if and only if this is true.
6045        dialect: the dialect used to parse the input expression.
6046        copy: whether to copy the expression.
6047        opts: other options to use to parse the input expressions.
6048
6049    Returns:
6050        The new Union instance.
6051    """
6052    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6053    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6054
6055    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:
6058def intersect(
6059    left: ExpOrStr,
6060    right: ExpOrStr,
6061    distinct: bool = True,
6062    dialect: DialectType = None,
6063    copy: bool = True,
6064    **opts,
6065) -> Intersect:
6066    """
6067    Initializes a syntax tree from one INTERSECT expression.
6068
6069    Example:
6070        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6071        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6072
6073    Args:
6074        left: the SQL code string corresponding to the left-hand side.
6075            If an `Expression` instance is passed, it will be used as-is.
6076        right: the SQL code string corresponding to the right-hand side.
6077            If an `Expression` instance is passed, it will be used as-is.
6078        distinct: set the DISTINCT flag if and only if this is true.
6079        dialect: the dialect used to parse the input expression.
6080        copy: whether to copy the expression.
6081        opts: other options to use to parse the input expressions.
6082
6083    Returns:
6084        The new Intersect instance.
6085    """
6086    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6087    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6088
6089    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:
6092def except_(
6093    left: ExpOrStr,
6094    right: ExpOrStr,
6095    distinct: bool = True,
6096    dialect: DialectType = None,
6097    copy: bool = True,
6098    **opts,
6099) -> Except:
6100    """
6101    Initializes a syntax tree from one EXCEPT expression.
6102
6103    Example:
6104        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6105        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6106
6107    Args:
6108        left: the SQL code string corresponding to the left-hand side.
6109            If an `Expression` instance is passed, it will be used as-is.
6110        right: the SQL code string corresponding to the right-hand side.
6111            If an `Expression` instance is passed, it will be used as-is.
6112        distinct: set the DISTINCT flag if and only if this is true.
6113        dialect: the dialect used to parse the input expression.
6114        copy: whether to copy the expression.
6115        opts: other options to use to parse the input expressions.
6116
6117    Returns:
6118        The new Except instance.
6119    """
6120    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6121    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6122
6123    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:
6126def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6127    """
6128    Initializes a syntax tree from one or multiple SELECT expressions.
6129
6130    Example:
6131        >>> select("col1", "col2").from_("tbl").sql()
6132        'SELECT col1, col2 FROM tbl'
6133
6134    Args:
6135        *expressions: the SQL code string to parse as the expressions of a
6136            SELECT statement. If an Expression instance is passed, this is used as-is.
6137        dialect: the dialect used to parse the input expressions (in the case that an
6138            input expression is a SQL string).
6139        **opts: other options to use to parse the input expressions (again, in the case
6140            that an input expression is a SQL string).
6141
6142    Returns:
6143        Select: the syntax tree for the SELECT statement.
6144    """
6145    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:
6148def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6149    """
6150    Initializes a syntax tree from a FROM expression.
6151
6152    Example:
6153        >>> from_("tbl").select("col1", "col2").sql()
6154        'SELECT col1, col2 FROM tbl'
6155
6156    Args:
6157        *expression: the SQL code string to parse as the FROM expressions of a
6158            SELECT statement. If an Expression instance is passed, this is used as-is.
6159        dialect: the dialect used to parse the input expression (in the case that the
6160            input expression is a SQL string).
6161        **opts: other options to use to parse the input expressions (again, in the case
6162            that the input expression is a SQL string).
6163
6164    Returns:
6165        Select: the syntax tree for the SELECT statement.
6166    """
6167    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:
6170def update(
6171    table: str | Table,
6172    properties: dict,
6173    where: t.Optional[ExpOrStr] = None,
6174    from_: t.Optional[ExpOrStr] = None,
6175    dialect: DialectType = None,
6176    **opts,
6177) -> Update:
6178    """
6179    Creates an update statement.
6180
6181    Example:
6182        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6183        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6184
6185    Args:
6186        *properties: dictionary of properties to set which are
6187            auto converted to sql objects eg None -> NULL
6188        where: sql conditional parsed into a WHERE statement
6189        from_: sql statement parsed into a FROM statement
6190        dialect: the dialect used to parse the input expressions.
6191        **opts: other options to use to parse the input expressions.
6192
6193    Returns:
6194        Update: the syntax tree for the UPDATE statement.
6195    """
6196    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6197    update_expr.set(
6198        "expressions",
6199        [
6200            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6201            for k, v in properties.items()
6202        ],
6203    )
6204    if from_:
6205        update_expr.set(
6206            "from",
6207            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6208        )
6209    if isinstance(where, Condition):
6210        where = Where(this=where)
6211    if where:
6212        update_expr.set(
6213            "where",
6214            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6215        )
6216    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:
6219def delete(
6220    table: ExpOrStr,
6221    where: t.Optional[ExpOrStr] = None,
6222    returning: t.Optional[ExpOrStr] = None,
6223    dialect: DialectType = None,
6224    **opts,
6225) -> Delete:
6226    """
6227    Builds a delete statement.
6228
6229    Example:
6230        >>> delete("my_table", where="id > 1").sql()
6231        'DELETE FROM my_table WHERE id > 1'
6232
6233    Args:
6234        where: sql conditional parsed into a WHERE statement
6235        returning: sql conditional parsed into a RETURNING statement
6236        dialect: the dialect used to parse the input expressions.
6237        **opts: other options to use to parse the input expressions.
6238
6239    Returns:
6240        Delete: the syntax tree for the DELETE statement.
6241    """
6242    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6243    if where:
6244        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6245    if returning:
6246        delete_expr = t.cast(
6247            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6248        )
6249    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:
6252def insert(
6253    expression: ExpOrStr,
6254    into: ExpOrStr,
6255    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6256    overwrite: t.Optional[bool] = None,
6257    returning: t.Optional[ExpOrStr] = None,
6258    dialect: DialectType = None,
6259    copy: bool = True,
6260    **opts,
6261) -> Insert:
6262    """
6263    Builds an INSERT statement.
6264
6265    Example:
6266        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6267        'INSERT INTO tbl VALUES (1, 2, 3)'
6268
6269    Args:
6270        expression: the sql string or expression of the INSERT statement
6271        into: the tbl to insert data to.
6272        columns: optionally the table's column names.
6273        overwrite: whether to INSERT OVERWRITE or not.
6274        returning: sql conditional parsed into a RETURNING statement
6275        dialect: the dialect used to parse the input expressions.
6276        copy: whether to copy the expression.
6277        **opts: other options to use to parse the input expressions.
6278
6279    Returns:
6280        Insert: the syntax tree for the INSERT statement.
6281    """
6282    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6283    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6284
6285    if columns:
6286        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6287
6288    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6289
6290    if returning:
6291        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6292
6293    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:
6296def condition(
6297    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6298) -> Condition:
6299    """
6300    Initialize a logical condition expression.
6301
6302    Example:
6303        >>> condition("x=1").sql()
6304        'x = 1'
6305
6306        This is helpful for composing larger logical syntax trees:
6307        >>> where = condition("x=1")
6308        >>> where = where.and_("y=1")
6309        >>> Select().from_("tbl").select("*").where(where).sql()
6310        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6311
6312    Args:
6313        *expression: the SQL code string to parse.
6314            If an Expression instance is passed, this is used as-is.
6315        dialect: the dialect used to parse the input expression (in the case that the
6316            input expression is a SQL string).
6317        copy: Whether to copy `expression` (only applies to expressions).
6318        **opts: other options to use to parse the input expressions (again, in the case
6319            that the input expression is a SQL string).
6320
6321    Returns:
6322        The new Condition instance
6323    """
6324    return maybe_parse(
6325        expression,
6326        into=Condition,
6327        dialect=dialect,
6328        copy=copy,
6329        **opts,
6330    )

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:
6333def and_(
6334    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6335) -> Condition:
6336    """
6337    Combine multiple conditions with an AND logical operator.
6338
6339    Example:
6340        >>> and_("x=1", and_("y=1", "z=1")).sql()
6341        'x = 1 AND (y = 1 AND z = 1)'
6342
6343    Args:
6344        *expressions: the SQL code strings to parse.
6345            If an Expression instance is passed, this is used as-is.
6346        dialect: the dialect used to parse the input expression.
6347        copy: whether to copy `expressions` (only applies to Expressions).
6348        **opts: other options to use to parse the input expressions.
6349
6350    Returns:
6351        And: the new condition
6352    """
6353    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:
6356def or_(
6357    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6358) -> Condition:
6359    """
6360    Combine multiple conditions with an OR logical operator.
6361
6362    Example:
6363        >>> or_("x=1", or_("y=1", "z=1")).sql()
6364        'x = 1 OR (y = 1 OR z = 1)'
6365
6366    Args:
6367        *expressions: the SQL code strings to parse.
6368            If an Expression instance is passed, this is used as-is.
6369        dialect: the dialect used to parse the input expression.
6370        copy: whether to copy `expressions` (only applies to Expressions).
6371        **opts: other options to use to parse the input expressions.
6372
6373    Returns:
6374        Or: the new condition
6375    """
6376    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:
6379def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6380    """
6381    Wrap a condition with a NOT operator.
6382
6383    Example:
6384        >>> not_("this_suit='black'").sql()
6385        "NOT this_suit = 'black'"
6386
6387    Args:
6388        expression: the SQL code string to parse.
6389            If an Expression instance is passed, this is used as-is.
6390        dialect: the dialect used to parse the input expression.
6391        copy: whether to copy the expression or not.
6392        **opts: other options to use to parse the input expressions.
6393
6394    Returns:
6395        The new condition.
6396    """
6397    this = condition(
6398        expression,
6399        dialect=dialect,
6400        copy=copy,
6401        **opts,
6402    )
6403    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:
6406def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6407    """
6408    Wrap an expression in parentheses.
6409
6410    Example:
6411        >>> paren("5 + 3").sql()
6412        '(5 + 3)'
6413
6414    Args:
6415        expression: the SQL code string to parse.
6416            If an Expression instance is passed, this is used as-is.
6417        copy: whether to copy the expression or not.
6418
6419    Returns:
6420        The wrapped expression.
6421    """
6422    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):
6438def to_identifier(name, quoted=None, copy=True):
6439    """Builds an identifier.
6440
6441    Args:
6442        name: The name to turn into an identifier.
6443        quoted: Whether to force quote the identifier.
6444        copy: Whether to copy name if it's an Identifier.
6445
6446    Returns:
6447        The identifier ast node.
6448    """
6449
6450    if name is None:
6451        return None
6452
6453    if isinstance(name, Identifier):
6454        identifier = maybe_copy(name, copy)
6455    elif isinstance(name, str):
6456        identifier = Identifier(
6457            this=name,
6458            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6459        )
6460    else:
6461        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6462    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:
6465def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6466    """
6467    Parses a given string into an identifier.
6468
6469    Args:
6470        name: The name to parse into an identifier.
6471        dialect: The dialect to parse against.
6472
6473    Returns:
6474        The identifier ast node.
6475    """
6476    try:
6477        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6478    except ParseError:
6479        expression = to_identifier(name)
6480
6481    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:
6487def to_interval(interval: str | Literal) -> Interval:
6488    """Builds an interval expression from a string like '1 day' or '5 months'."""
6489    if isinstance(interval, Literal):
6490        if not interval.is_string:
6491            raise ValueError("Invalid interval string.")
6492
6493        interval = interval.this
6494
6495    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6496
6497    if not interval_parts:
6498        raise ValueError("Invalid interval string.")
6499
6500    return Interval(
6501        this=Literal.string(interval_parts.group(1)),
6502        unit=Var(this=interval_parts.group(2).upper()),
6503    )

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]:
6514def to_table(
6515    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6516) -> t.Optional[Table]:
6517    """
6518    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6519    If a table is passed in then that table is returned.
6520
6521    Args:
6522        sql_path: a `[catalog].[schema].[table]` string.
6523        dialect: the source dialect according to which the table name will be parsed.
6524        copy: Whether to copy a table if it is passed in.
6525        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6526
6527    Returns:
6528        A table expression.
6529    """
6530    if sql_path is None or isinstance(sql_path, Table):
6531        return maybe_copy(sql_path, copy=copy)
6532    if not isinstance(sql_path, str):
6533        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6534
6535    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6536    if table:
6537        for k, v in kwargs.items():
6538            table.set(k, v)
6539
6540    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:
6543def to_column(sql_path: str | Column, **kwargs) -> Column:
6544    """
6545    Create a column from a `[table].[column]` sql path. Schema is optional.
6546
6547    If a column is passed in then that column is returned.
6548
6549    Args:
6550        sql_path: `[table].[column]` string
6551    Returns:
6552        Table: A column expression
6553    """
6554    if sql_path is None or isinstance(sql_path, Column):
6555        return sql_path
6556    if not isinstance(sql_path, str):
6557        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6558    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):
6561def alias_(
6562    expression: ExpOrStr,
6563    alias: t.Optional[str | Identifier],
6564    table: bool | t.Sequence[str | Identifier] = False,
6565    quoted: t.Optional[bool] = None,
6566    dialect: DialectType = None,
6567    copy: bool = True,
6568    **opts,
6569):
6570    """Create an Alias expression.
6571
6572    Example:
6573        >>> alias_('foo', 'bar').sql()
6574        'foo AS bar'
6575
6576        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6577        '(SELECT 1, 2) AS bar(a, b)'
6578
6579    Args:
6580        expression: the SQL code strings to parse.
6581            If an Expression instance is passed, this is used as-is.
6582        alias: the alias name to use. If the name has
6583            special characters it is quoted.
6584        table: Whether to create a table alias, can also be a list of columns.
6585        quoted: whether to quote the alias
6586        dialect: the dialect used to parse the input expression.
6587        copy: Whether to copy the expression.
6588        **opts: other options to use to parse the input expressions.
6589
6590    Returns:
6591        Alias: the aliased expression
6592    """
6593    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6594    alias = to_identifier(alias, quoted=quoted)
6595
6596    if table:
6597        table_alias = TableAlias(this=alias)
6598        exp.set("alias", table_alias)
6599
6600        if not isinstance(table, bool):
6601            for column in table:
6602                table_alias.append("columns", to_identifier(column, quoted=quoted))
6603
6604        return exp
6605
6606    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6607    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6608    # for the complete Window expression.
6609    #
6610    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6611
6612    if "alias" in exp.arg_types and not isinstance(exp, Window):
6613        exp.set("alias", alias)
6614        return exp
6615    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:
6618def subquery(
6619    expression: ExpOrStr,
6620    alias: t.Optional[Identifier | str] = None,
6621    dialect: DialectType = None,
6622    **opts,
6623) -> Select:
6624    """
6625    Build a subquery expression.
6626
6627    Example:
6628        >>> subquery('select x from tbl', 'bar').select('x').sql()
6629        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6630
6631    Args:
6632        expression: the SQL code strings to parse.
6633            If an Expression instance is passed, this is used as-is.
6634        alias: the alias name to use.
6635        dialect: the dialect used to parse the input expression.
6636        **opts: other options to use to parse the input expressions.
6637
6638    Returns:
6639        A new Select instance with the subquery expression included.
6640    """
6641
6642    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6643    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):
6674def column(
6675    col,
6676    table=None,
6677    db=None,
6678    catalog=None,
6679    *,
6680    fields=None,
6681    quoted=None,
6682    copy=True,
6683):
6684    """
6685    Build a Column.
6686
6687    Args:
6688        col: Column name.
6689        table: Table name.
6690        db: Database name.
6691        catalog: Catalog name.
6692        fields: Additional fields using dots.
6693        quoted: Whether to force quotes on the column's identifiers.
6694        copy: Whether to copy identifiers if passed in.
6695
6696    Returns:
6697        The new Column instance.
6698    """
6699    this = Column(
6700        this=to_identifier(col, quoted=quoted, copy=copy),
6701        table=to_identifier(table, quoted=quoted, copy=copy),
6702        db=to_identifier(db, quoted=quoted, copy=copy),
6703        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6704    )
6705
6706    if fields:
6707        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6708    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:
6711def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6712    """Cast an expression to a data type.
6713
6714    Example:
6715        >>> cast('x + 1', 'int').sql()
6716        'CAST(x + 1 AS INT)'
6717
6718    Args:
6719        expression: The expression to cast.
6720        to: The datatype to cast to.
6721        copy: Whether to copy the supplied expressions.
6722
6723    Returns:
6724        The new Cast instance.
6725    """
6726    expression = maybe_parse(expression, copy=copy, **opts)
6727    data_type = DataType.build(to, copy=copy, **opts)
6728    expression = Cast(this=expression, to=data_type)
6729    expression.type = data_type
6730    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:
6733def table_(
6734    table: Identifier | str,
6735    db: t.Optional[Identifier | str] = None,
6736    catalog: t.Optional[Identifier | str] = None,
6737    quoted: t.Optional[bool] = None,
6738    alias: t.Optional[Identifier | str] = None,
6739) -> Table:
6740    """Build a Table.
6741
6742    Args:
6743        table: Table name.
6744        db: Database name.
6745        catalog: Catalog name.
6746        quote: Whether to force quotes on the table's identifiers.
6747        alias: Table's alias.
6748
6749    Returns:
6750        The new Table instance.
6751    """
6752    return Table(
6753        this=to_identifier(table, quoted=quoted) if table else None,
6754        db=to_identifier(db, quoted=quoted) if db else None,
6755        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6756        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6757    )

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:
6760def values(
6761    values: t.Iterable[t.Tuple[t.Any, ...]],
6762    alias: t.Optional[str] = None,
6763    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6764) -> Values:
6765    """Build VALUES statement.
6766
6767    Example:
6768        >>> values([(1, '2')]).sql()
6769        "VALUES (1, '2')"
6770
6771    Args:
6772        values: values statements that will be converted to SQL
6773        alias: optional alias
6774        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6775         If either are provided then an alias is also required.
6776
6777    Returns:
6778        Values: the Values expression object
6779    """
6780    if columns and not alias:
6781        raise ValueError("Alias is required when providing columns")
6782
6783    return Values(
6784        expressions=[convert(tup) for tup in values],
6785        alias=(
6786            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6787            if columns
6788            else (TableAlias(this=to_identifier(alias)) if alias else None)
6789        ),
6790    )

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:
6793def var(name: t.Optional[ExpOrStr]) -> Var:
6794    """Build a SQL variable.
6795
6796    Example:
6797        >>> repr(var('x'))
6798        'Var(this=x)'
6799
6800        >>> repr(var(column('x', table='y')))
6801        'Var(this=x)'
6802
6803    Args:
6804        name: The name of the var or an expression who's name will become the var.
6805
6806    Returns:
6807        The new variable node.
6808    """
6809    if not name:
6810        raise ValueError("Cannot convert empty name into var.")
6811
6812    if isinstance(name, Expression):
6813        name = name.name
6814    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:
6817def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6818    """Build ALTER TABLE... RENAME... expression
6819
6820    Args:
6821        old_name: The old name of the table
6822        new_name: The new name of the table
6823
6824    Returns:
6825        Alter table expression
6826    """
6827    old_table = to_table(old_name)
6828    new_table = to_table(new_name)
6829    return AlterTable(
6830        this=old_table,
6831        actions=[
6832            RenameTable(this=new_table),
6833        ],
6834    )

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:
6837def rename_column(
6838    table_name: str | Table,
6839    old_column_name: str | Column,
6840    new_column_name: str | Column,
6841    exists: t.Optional[bool] = None,
6842) -> AlterTable:
6843    """Build ALTER TABLE... RENAME COLUMN... expression
6844
6845    Args:
6846        table_name: Name of the table
6847        old_column: The old name of the column
6848        new_column: The new name of the column
6849        exists: Whether to add the `IF EXISTS` clause
6850
6851    Returns:
6852        Alter table expression
6853    """
6854    table = to_table(table_name)
6855    old_column = to_column(old_column_name)
6856    new_column = to_column(new_column_name)
6857    return AlterTable(
6858        this=table,
6859        actions=[
6860            RenameColumn(this=old_column, to=new_column, exists=exists),
6861        ],
6862    )

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:
6865def convert(value: t.Any, copy: bool = False) -> Expression:
6866    """Convert a python value into an expression object.
6867
6868    Raises an error if a conversion is not possible.
6869
6870    Args:
6871        value: A python object.
6872        copy: Whether to copy `value` (only applies to Expressions and collections).
6873
6874    Returns:
6875        Expression: the equivalent expression object.
6876    """
6877    if isinstance(value, Expression):
6878        return maybe_copy(value, copy)
6879    if isinstance(value, str):
6880        return Literal.string(value)
6881    if isinstance(value, bool):
6882        return Boolean(this=value)
6883    if value is None or (isinstance(value, float) and math.isnan(value)):
6884        return null()
6885    if isinstance(value, numbers.Number):
6886        return Literal.number(value)
6887    if isinstance(value, datetime.datetime):
6888        datetime_literal = Literal.string(
6889            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6890        )
6891        return TimeStrToTime(this=datetime_literal)
6892    if isinstance(value, datetime.date):
6893        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6894        return DateStrToDate(this=date_literal)
6895    if isinstance(value, tuple):
6896        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6897    if isinstance(value, list):
6898        return Array(expressions=[convert(v, copy=copy) for v in value])
6899    if isinstance(value, dict):
6900        return Map(
6901            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6902            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6903        )
6904    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:
6907def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6908    """
6909    Replace children of an expression with the result of a lambda fun(child) -> exp.
6910    """
6911    for k, v in expression.args.items():
6912        is_list_arg = type(v) is list
6913
6914        child_nodes = v if is_list_arg else [v]
6915        new_child_nodes = []
6916
6917        for cn in child_nodes:
6918            if isinstance(cn, Expression):
6919                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6920                    new_child_nodes.append(child_node)
6921                    child_node.parent = expression
6922                    child_node.arg_key = k
6923            else:
6924                new_child_nodes.append(cn)
6925
6926        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]:
6929def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6930    """
6931    Return all table names referenced through columns in an expression.
6932
6933    Example:
6934        >>> import sqlglot
6935        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6936        ['a', 'c']
6937
6938    Args:
6939        expression: expression to find table names.
6940        exclude: a table name to exclude
6941
6942    Returns:
6943        A list of unique names.
6944    """
6945    return {
6946        table
6947        for table in (column.table for column in expression.find_all(Column))
6948        if table and table != exclude
6949    }

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:
6952def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6953    """Get the full name of a table as a string.
6954
6955    Args:
6956        table: Table expression node or string.
6957        dialect: The dialect to generate the table name for.
6958        identify: Determines when an identifier should be quoted. Possible values are:
6959            False (default): Never quote, except in cases where it's mandatory by the dialect.
6960            True: Always quote.
6961
6962    Examples:
6963        >>> from sqlglot import exp, parse_one
6964        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6965        'a.b.c'
6966
6967    Returns:
6968        The table name.
6969    """
6970
6971    table = maybe_parse(table, into=Table, dialect=dialect)
6972
6973    if not table:
6974        raise ValueError(f"Cannot parse {table}")
6975
6976    return ".".join(
6977        (
6978            part.sql(dialect=dialect, identify=True, copy=False)
6979            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6980            else part.name
6981        )
6982        for part in table.parts
6983    )

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:
6986def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6987    """Returns a case normalized table name without quotes.
6988
6989    Args:
6990        table: the table to normalize
6991        dialect: the dialect to use for normalization rules
6992        copy: whether to copy the expression.
6993
6994    Examples:
6995        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6996        'A-B.c'
6997    """
6998    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6999
7000    return ".".join(
7001        p.name
7002        for p in normalize_identifiers(
7003            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7004        ).parts
7005    )

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

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:
7256def tuple_(
7257    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7258) -> Tuple:
7259    """
7260    Returns an tuple.
7261
7262    Examples:
7263        >>> tuple_(1, 'x').sql()
7264        '(1, x)'
7265
7266    Args:
7267        expressions: the expressions to add to the tuple.
7268        copy: whether to copy the argument expressions.
7269        dialect: the source dialect.
7270        kwargs: the kwargs used to instantiate the function of interest.
7271
7272    Returns:
7273        A tuple expression.
7274    """
7275    return Tuple(
7276        expressions=[
7277            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7278            for expression in expressions
7279        ]
7280    )

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:
7283def true() -> Boolean:
7284    """
7285    Returns a true Boolean expression.
7286    """
7287    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7290def false() -> Boolean:
7291    """
7292    Returns a false Boolean expression.
7293    """
7294    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7297def null() -> Null:
7298    """
7299    Returns a Null expression.
7300    """
7301    return Null()

Returns a Null expression.