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

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

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):
1753class Drop(Expression):
1754    arg_types = {
1755        "this": False,
1756        "kind": False,
1757        "exists": False,
1758        "temporary": False,
1759        "materialized": False,
1760        "cascade": False,
1761        "constraints": False,
1762        "purge": False,
1763    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1766class Filter(Expression):
1767    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1770class Check(Expression):
1771    pass
key = 'check'
class Connect(Expression):
1775class Connect(Expression):
1776    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1779class Prior(Expression):
1780    pass
key = 'prior'
class Directory(Expression):
1783class Directory(Expression):
1784    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1785    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1788class ForeignKey(Expression):
1789    arg_types = {
1790        "expressions": True,
1791        "reference": False,
1792        "delete": False,
1793        "update": False,
1794    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1797class ColumnPrefix(Expression):
1798    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1801class PrimaryKey(Expression):
1802    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1807class Into(Expression):
1808    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1811class From(Expression):
1812    @property
1813    def name(self) -> str:
1814        return self.this.name
1815
1816    @property
1817    def alias_or_name(self) -> str:
1818        return self.this.alias_or_name
name: str
1812    @property
1813    def name(self) -> str:
1814        return self.this.name
alias_or_name: str
1816    @property
1817    def alias_or_name(self) -> str:
1818        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1821class Having(Expression):
1822    pass
key = 'having'
class Hint(Expression):
1825class Hint(Expression):
1826    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1829class JoinHint(Expression):
1830    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1833class Identifier(Expression):
1834    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1835
1836    @property
1837    def quoted(self) -> bool:
1838        return bool(self.args.get("quoted"))
1839
1840    @property
1841    def hashable_args(self) -> t.Any:
1842        return (self.this, self.quoted)
1843
1844    @property
1845    def output_name(self) -> str:
1846        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1836    @property
1837    def quoted(self) -> bool:
1838        return bool(self.args.get("quoted"))
hashable_args: Any
1840    @property
1841    def hashable_args(self) -> t.Any:
1842        return (self.this, self.quoted)
output_name: str
1844    @property
1845    def output_name(self) -> str:
1846        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):
1850class Opclass(Expression):
1851    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1854class Index(Expression):
1855    arg_types = {
1856        "this": False,
1857        "table": False,
1858        "using": False,
1859        "where": False,
1860        "columns": False,
1861        "unique": False,
1862        "primary": False,
1863        "amp": False,  # teradata
1864        "include": False,
1865        "partition_by": False,  # teradata
1866    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'include': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1869class Insert(DDL, DML):
1870    arg_types = {
1871        "hint": False,
1872        "with": False,
1873        "this": True,
1874        "expression": False,
1875        "conflict": False,
1876        "returning": False,
1877        "overwrite": False,
1878        "exists": False,
1879        "partition": False,
1880        "alternative": False,
1881        "where": False,
1882        "ignore": False,
1883        "by_name": False,
1884    }
1885
1886    def with_(
1887        self,
1888        alias: ExpOrStr,
1889        as_: ExpOrStr,
1890        recursive: t.Optional[bool] = None,
1891        append: bool = True,
1892        dialect: DialectType = None,
1893        copy: bool = True,
1894        **opts,
1895    ) -> Insert:
1896        """
1897        Append to or set the common table expressions.
1898
1899        Example:
1900            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1901            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1902
1903        Args:
1904            alias: the SQL code string to parse as the table name.
1905                If an `Expression` instance is passed, this is used as-is.
1906            as_: the SQL code string to parse as the table expression.
1907                If an `Expression` instance is passed, it will be used as-is.
1908            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1909            append: if `True`, add to any existing expressions.
1910                Otherwise, this resets the expressions.
1911            dialect: the dialect used to parse the input expression.
1912            copy: if `False`, modify this expression instance in-place.
1913            opts: other options to use to parse the input expressions.
1914
1915        Returns:
1916            The modified expression.
1917        """
1918        return _apply_cte_builder(
1919            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1920        )
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:
1886    def with_(
1887        self,
1888        alias: ExpOrStr,
1889        as_: ExpOrStr,
1890        recursive: t.Optional[bool] = None,
1891        append: bool = True,
1892        dialect: DialectType = None,
1893        copy: bool = True,
1894        **opts,
1895    ) -> Insert:
1896        """
1897        Append to or set the common table expressions.
1898
1899        Example:
1900            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1901            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1902
1903        Args:
1904            alias: the SQL code string to parse as the table name.
1905                If an `Expression` instance is passed, this is used as-is.
1906            as_: the SQL code string to parse as the table expression.
1907                If an `Expression` instance is passed, it will be used as-is.
1908            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1909            append: if `True`, add to any existing expressions.
1910                Otherwise, this resets the expressions.
1911            dialect: the dialect used to parse the input expression.
1912            copy: if `False`, modify this expression instance in-place.
1913            opts: other options to use to parse the input expressions.
1914
1915        Returns:
1916            The modified expression.
1917        """
1918        return _apply_cte_builder(
1919            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1920        )

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):
1923class OnConflict(Expression):
1924    arg_types = {
1925        "duplicate": False,
1926        "expressions": False,
1927        "action": False,
1928        "conflict_keys": False,
1929        "constraint": False,
1930    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1933class Returning(Expression):
1934    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1938class Introducer(Expression):
1939    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1943class National(Expression):
1944    pass
key = 'national'
class LoadData(Expression):
1947class LoadData(Expression):
1948    arg_types = {
1949        "this": True,
1950        "local": False,
1951        "overwrite": False,
1952        "inpath": True,
1953        "partition": False,
1954        "input_format": False,
1955        "serde": False,
1956    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1959class Partition(Expression):
1960    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
1963class PartitionRange(Expression):
1964    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
1967class Fetch(Expression):
1968    arg_types = {
1969        "direction": False,
1970        "count": False,
1971        "percent": False,
1972        "with_ties": False,
1973    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1976class Group(Expression):
1977    arg_types = {
1978        "expressions": False,
1979        "grouping_sets": False,
1980        "cube": False,
1981        "rollup": False,
1982        "totals": False,
1983        "all": False,
1984    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1987class Lambda(Expression):
1988    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1991class Limit(Expression):
1992    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):
1995class Literal(Condition):
1996    arg_types = {"this": True, "is_string": True}
1997
1998    @property
1999    def hashable_args(self) -> t.Any:
2000        return (self.this, self.args.get("is_string"))
2001
2002    @classmethod
2003    def number(cls, number) -> Literal:
2004        return cls(this=str(number), is_string=False)
2005
2006    @classmethod
2007    def string(cls, string) -> Literal:
2008        return cls(this=str(string), is_string=True)
2009
2010    @property
2011    def output_name(self) -> str:
2012        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1998    @property
1999    def hashable_args(self) -> t.Any:
2000        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2002    @classmethod
2003    def number(cls, number) -> Literal:
2004        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2006    @classmethod
2007    def string(cls, string) -> Literal:
2008        return cls(this=str(string), is_string=True)
output_name: str
2010    @property
2011    def output_name(self) -> str:
2012        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):
2015class Join(Expression):
2016    arg_types = {
2017        "this": True,
2018        "on": False,
2019        "side": False,
2020        "kind": False,
2021        "using": False,
2022        "method": False,
2023        "global": False,
2024        "hint": False,
2025    }
2026
2027    @property
2028    def method(self) -> str:
2029        return self.text("method").upper()
2030
2031    @property
2032    def kind(self) -> str:
2033        return self.text("kind").upper()
2034
2035    @property
2036    def side(self) -> str:
2037        return self.text("side").upper()
2038
2039    @property
2040    def hint(self) -> str:
2041        return self.text("hint").upper()
2042
2043    @property
2044    def alias_or_name(self) -> str:
2045        return self.this.alias_or_name
2046
2047    def on(
2048        self,
2049        *expressions: t.Optional[ExpOrStr],
2050        append: bool = True,
2051        dialect: DialectType = None,
2052        copy: bool = True,
2053        **opts,
2054    ) -> Join:
2055        """
2056        Append to or set the ON expressions.
2057
2058        Example:
2059            >>> import sqlglot
2060            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2061            'JOIN x ON y = 1'
2062
2063        Args:
2064            *expressions: the SQL code strings to parse.
2065                If an `Expression` instance is passed, it will be used as-is.
2066                Multiple expressions are combined with an AND operator.
2067            append: if `True`, AND the new expressions to any existing expression.
2068                Otherwise, this resets the expression.
2069            dialect: the dialect used to parse the input expressions.
2070            copy: if `False`, modify this expression instance in-place.
2071            opts: other options to use to parse the input expressions.
2072
2073        Returns:
2074            The modified Join expression.
2075        """
2076        join = _apply_conjunction_builder(
2077            *expressions,
2078            instance=self,
2079            arg="on",
2080            append=append,
2081            dialect=dialect,
2082            copy=copy,
2083            **opts,
2084        )
2085
2086        if join.kind == "CROSS":
2087            join.set("kind", None)
2088
2089        return join
2090
2091    def using(
2092        self,
2093        *expressions: t.Optional[ExpOrStr],
2094        append: bool = True,
2095        dialect: DialectType = None,
2096        copy: bool = True,
2097        **opts,
2098    ) -> Join:
2099        """
2100        Append to or set the USING expressions.
2101
2102        Example:
2103            >>> import sqlglot
2104            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2105            'JOIN x USING (foo, bla)'
2106
2107        Args:
2108            *expressions: the SQL code strings to parse.
2109                If an `Expression` instance is passed, it will be used as-is.
2110            append: if `True`, concatenate the new expressions to the existing "using" list.
2111                Otherwise, this resets the expression.
2112            dialect: the dialect used to parse the input expressions.
2113            copy: if `False`, modify this expression instance in-place.
2114            opts: other options to use to parse the input expressions.
2115
2116        Returns:
2117            The modified Join expression.
2118        """
2119        join = _apply_list_builder(
2120            *expressions,
2121            instance=self,
2122            arg="using",
2123            append=append,
2124            dialect=dialect,
2125            copy=copy,
2126            **opts,
2127        )
2128
2129        if join.kind == "CROSS":
2130            join.set("kind", None)
2131
2132        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2027    @property
2028    def method(self) -> str:
2029        return self.text("method").upper()
kind: str
2031    @property
2032    def kind(self) -> str:
2033        return self.text("kind").upper()
side: str
2035    @property
2036    def side(self) -> str:
2037        return self.text("side").upper()
hint: str
2039    @property
2040    def hint(self) -> str:
2041        return self.text("hint").upper()
alias_or_name: str
2043    @property
2044    def alias_or_name(self) -> str:
2045        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:
2047    def on(
2048        self,
2049        *expressions: t.Optional[ExpOrStr],
2050        append: bool = True,
2051        dialect: DialectType = None,
2052        copy: bool = True,
2053        **opts,
2054    ) -> Join:
2055        """
2056        Append to or set the ON expressions.
2057
2058        Example:
2059            >>> import sqlglot
2060            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2061            'JOIN x ON y = 1'
2062
2063        Args:
2064            *expressions: the SQL code strings to parse.
2065                If an `Expression` instance is passed, it will be used as-is.
2066                Multiple expressions are combined with an AND operator.
2067            append: if `True`, AND the new expressions to any existing expression.
2068                Otherwise, this resets the expression.
2069            dialect: the dialect used to parse the input expressions.
2070            copy: if `False`, modify this expression instance in-place.
2071            opts: other options to use to parse the input expressions.
2072
2073        Returns:
2074            The modified Join expression.
2075        """
2076        join = _apply_conjunction_builder(
2077            *expressions,
2078            instance=self,
2079            arg="on",
2080            append=append,
2081            dialect=dialect,
2082            copy=copy,
2083            **opts,
2084        )
2085
2086        if join.kind == "CROSS":
2087            join.set("kind", None)
2088
2089        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:
2091    def using(
2092        self,
2093        *expressions: t.Optional[ExpOrStr],
2094        append: bool = True,
2095        dialect: DialectType = None,
2096        copy: bool = True,
2097        **opts,
2098    ) -> Join:
2099        """
2100        Append to or set the USING expressions.
2101
2102        Example:
2103            >>> import sqlglot
2104            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2105            'JOIN x USING (foo, bla)'
2106
2107        Args:
2108            *expressions: the SQL code strings to parse.
2109                If an `Expression` instance is passed, it will be used as-is.
2110            append: if `True`, concatenate the new expressions to the existing "using" list.
2111                Otherwise, this resets the expression.
2112            dialect: the dialect used to parse the input expressions.
2113            copy: if `False`, modify this expression instance in-place.
2114            opts: other options to use to parse the input expressions.
2115
2116        Returns:
2117            The modified Join expression.
2118        """
2119        join = _apply_list_builder(
2120            *expressions,
2121            instance=self,
2122            arg="using",
2123            append=append,
2124            dialect=dialect,
2125            copy=copy,
2126            **opts,
2127        )
2128
2129        if join.kind == "CROSS":
2130            join.set("kind", None)
2131
2132        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):
2135class Lateral(UDTF):
2136    arg_types = {
2137        "this": True,
2138        "view": False,
2139        "outer": False,
2140        "alias": False,
2141        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2142    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2145class MatchRecognize(Expression):
2146    arg_types = {
2147        "partition_by": False,
2148        "order": False,
2149        "measures": False,
2150        "rows": False,
2151        "after": False,
2152        "pattern": False,
2153        "define": False,
2154        "alias": False,
2155    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2160class Final(Expression):
2161    pass
key = 'final'
class Offset(Expression):
2164class Offset(Expression):
2165    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2168class Order(Expression):
2169    arg_types = {
2170        "this": False,
2171        "expressions": True,
2172        "interpolate": False,
2173        "siblings": False,
2174    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2178class WithFill(Expression):
2179    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2184class Cluster(Order):
2185    pass
key = 'cluster'
class Distribute(Order):
2188class Distribute(Order):
2189    pass
key = 'distribute'
class Sort(Order):
2192class Sort(Order):
2193    pass
key = 'sort'
class Ordered(Expression):
2196class Ordered(Expression):
2197    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):
2200class Property(Expression):
2201    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2204class AlgorithmProperty(Property):
2205    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2208class AutoIncrementProperty(Property):
2209    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2213class AutoRefreshProperty(Property):
2214    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2217class BlockCompressionProperty(Property):
2218    arg_types = {
2219        "autotemp": False,
2220        "always": False,
2221        "default": False,
2222        "manual": False,
2223        "never": False,
2224    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2227class CharacterSetProperty(Property):
2228    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2231class ChecksumProperty(Property):
2232    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2235class CollateProperty(Property):
2236    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2239class CopyGrantsProperty(Property):
2240    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2243class DataBlocksizeProperty(Property):
2244    arg_types = {
2245        "size": False,
2246        "units": False,
2247        "minimum": False,
2248        "maximum": False,
2249        "default": False,
2250    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2253class DefinerProperty(Property):
2254    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2257class DistKeyProperty(Property):
2258    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2261class DistStyleProperty(Property):
2262    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2265class EngineProperty(Property):
2266    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2269class HeapProperty(Property):
2270    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2273class ToTableProperty(Property):
2274    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2277class ExecuteAsProperty(Property):
2278    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2281class ExternalProperty(Property):
2282    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2285class FallbackProperty(Property):
2286    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2289class FileFormatProperty(Property):
2290    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2293class FreespaceProperty(Property):
2294    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2297class GlobalProperty(Property):
2298    arg_types = {}
arg_types = {}
key = 'globalproperty'
class InheritsProperty(Property):
2301class InheritsProperty(Property):
2302    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2305class InputModelProperty(Property):
2306    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2309class OutputModelProperty(Property):
2310    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2313class IsolatedLoadingProperty(Property):
2314    arg_types = {
2315        "no": False,
2316        "concurrent": False,
2317        "for_all": False,
2318        "for_insert": False,
2319        "for_none": False,
2320    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2323class JournalProperty(Property):
2324    arg_types = {
2325        "no": False,
2326        "dual": False,
2327        "before": False,
2328        "local": False,
2329        "after": False,
2330    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2333class LanguageProperty(Property):
2334    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2338class ClusteredByProperty(Property):
2339    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2342class DictProperty(Property):
2343    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2346class DictSubProperty(Property):
2347    pass
key = 'dictsubproperty'
class DictRange(Property):
2350class DictRange(Property):
2351    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2356class OnCluster(Property):
2357    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2360class LikeProperty(Property):
2361    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2364class LocationProperty(Property):
2365    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2368class LockProperty(Property):
2369    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2372class LockingProperty(Property):
2373    arg_types = {
2374        "this": False,
2375        "kind": True,
2376        "for_or_in": False,
2377        "lock_type": True,
2378        "override": False,
2379    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2382class LogProperty(Property):
2383    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2386class MaterializedProperty(Property):
2387    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2390class MergeBlockRatioProperty(Property):
2391    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):
2394class NoPrimaryIndexProperty(Property):
2395    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2398class OnProperty(Property):
2399    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2402class OnCommitProperty(Property):
2403    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2406class PartitionedByProperty(Property):
2407    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2411class PartitionBoundSpec(Expression):
2412    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2413    arg_types = {
2414        "this": False,
2415        "expression": False,
2416        "from_expressions": False,
2417        "to_expressions": False,
2418    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2421class PartitionedOfProperty(Property):
2422    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2423    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2426class RemoteWithConnectionModelProperty(Property):
2427    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2430class ReturnsProperty(Property):
2431    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2434class RowFormatProperty(Property):
2435    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2438class RowFormatDelimitedProperty(Property):
2439    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2440    arg_types = {
2441        "fields": False,
2442        "escaped": False,
2443        "collection_items": False,
2444        "map_keys": False,
2445        "lines": False,
2446        "null": False,
2447        "serde": False,
2448    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2451class RowFormatSerdeProperty(Property):
2452    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2456class QueryTransform(Expression):
2457    arg_types = {
2458        "expressions": True,
2459        "command_script": True,
2460        "schema": False,
2461        "row_format_before": False,
2462        "record_writer": False,
2463        "row_format_after": False,
2464        "record_reader": False,
2465    }
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):
2468class SampleProperty(Property):
2469    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2472class SchemaCommentProperty(Property):
2473    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2476class SerdeProperties(Property):
2477    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2480class SetProperty(Property):
2481    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2484class SharingProperty(Property):
2485    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2488class SetConfigProperty(Property):
2489    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2492class SettingsProperty(Property):
2493    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2496class SortKeyProperty(Property):
2497    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2500class SqlReadWriteProperty(Property):
2501    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2504class SqlSecurityProperty(Property):
2505    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2508class StabilityProperty(Property):
2509    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2512class TemporaryProperty(Property):
2513    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2516class TransformModelProperty(Property):
2517    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2520class TransientProperty(Property):
2521    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2524class UnloggedProperty(Property):
2525    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class VolatileProperty(Property):
2528class VolatileProperty(Property):
2529    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2532class WithDataProperty(Property):
2533    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2536class WithJournalTableProperty(Property):
2537    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2540class WithSystemVersioningProperty(Property):
2541    # this -> history table name, expression -> data consistency check
2542    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2545class Properties(Expression):
2546    arg_types = {"expressions": True}
2547
2548    NAME_TO_PROPERTY = {
2549        "ALGORITHM": AlgorithmProperty,
2550        "AUTO_INCREMENT": AutoIncrementProperty,
2551        "CHARACTER SET": CharacterSetProperty,
2552        "CLUSTERED_BY": ClusteredByProperty,
2553        "COLLATE": CollateProperty,
2554        "COMMENT": SchemaCommentProperty,
2555        "DEFINER": DefinerProperty,
2556        "DISTKEY": DistKeyProperty,
2557        "DISTSTYLE": DistStyleProperty,
2558        "ENGINE": EngineProperty,
2559        "EXECUTE AS": ExecuteAsProperty,
2560        "FORMAT": FileFormatProperty,
2561        "LANGUAGE": LanguageProperty,
2562        "LOCATION": LocationProperty,
2563        "LOCK": LockProperty,
2564        "PARTITIONED_BY": PartitionedByProperty,
2565        "RETURNS": ReturnsProperty,
2566        "ROW_FORMAT": RowFormatProperty,
2567        "SORTKEY": SortKeyProperty,
2568    }
2569
2570    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2571
2572    # CREATE property locations
2573    # Form: schema specified
2574    #   create [POST_CREATE]
2575    #     table a [POST_NAME]
2576    #     (b int) [POST_SCHEMA]
2577    #     with ([POST_WITH])
2578    #     index (b) [POST_INDEX]
2579    #
2580    # Form: alias selection
2581    #   create [POST_CREATE]
2582    #     table a [POST_NAME]
2583    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2584    #     index (c) [POST_INDEX]
2585    class Location(AutoName):
2586        POST_CREATE = auto()
2587        POST_NAME = auto()
2588        POST_SCHEMA = auto()
2589        POST_WITH = auto()
2590        POST_ALIAS = auto()
2591        POST_EXPRESSION = auto()
2592        POST_INDEX = auto()
2593        UNSUPPORTED = auto()
2594
2595    @classmethod
2596    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2597        expressions = []
2598        for key, value in properties_dict.items():
2599            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2600            if property_cls:
2601                expressions.append(property_cls(this=convert(value)))
2602            else:
2603                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2604
2605        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:
2595    @classmethod
2596    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2597        expressions = []
2598        for key, value in properties_dict.items():
2599            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2600            if property_cls:
2601                expressions.append(property_cls(this=convert(value)))
2602            else:
2603                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2604
2605        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2585    class Location(AutoName):
2586        POST_CREATE = auto()
2587        POST_NAME = auto()
2588        POST_SCHEMA = auto()
2589        POST_WITH = auto()
2590        POST_ALIAS = auto()
2591        POST_EXPRESSION = auto()
2592        POST_INDEX = auto()
2593        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):
2608class Qualify(Expression):
2609    pass
key = 'qualify'
class InputOutputFormat(Expression):
2612class InputOutputFormat(Expression):
2613    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2617class Return(Expression):
2618    pass
key = 'return'
class Reference(Expression):
2621class Reference(Expression):
2622    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2625class Tuple(Expression):
2626    arg_types = {"expressions": False}
2627
2628    def isin(
2629        self,
2630        *expressions: t.Any,
2631        query: t.Optional[ExpOrStr] = None,
2632        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> In:
2636        return In(
2637            this=maybe_copy(self, copy),
2638            expressions=[convert(e, copy=copy) for e in expressions],
2639            query=maybe_parse(query, copy=copy, **opts) if query else None,
2640            unnest=(
2641                Unnest(
2642                    expressions=[
2643                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2644                        for e in ensure_list(unnest)
2645                    ]
2646                )
2647                if unnest
2648                else None
2649            ),
2650        )
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:
2628    def isin(
2629        self,
2630        *expressions: t.Any,
2631        query: t.Optional[ExpOrStr] = None,
2632        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> In:
2636        return In(
2637            this=maybe_copy(self, copy),
2638            expressions=[convert(e, copy=copy) for e in expressions],
2639            query=maybe_parse(query, copy=copy, **opts) if query else None,
2640            unnest=(
2641                Unnest(
2642                    expressions=[
2643                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2644                        for e in ensure_list(unnest)
2645                    ]
2646                )
2647                if unnest
2648                else None
2649            ),
2650        )
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):
2681class QueryOption(Expression):
2682    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2686class WithTableHint(Expression):
2687    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2691class IndexTableHint(Expression):
2692    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2696class HistoricalData(Expression):
2697    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2700class Table(Expression):
2701    arg_types = {
2702        "this": False,
2703        "alias": False,
2704        "db": False,
2705        "catalog": False,
2706        "laterals": False,
2707        "joins": False,
2708        "pivots": False,
2709        "hints": False,
2710        "system_time": False,
2711        "version": False,
2712        "format": False,
2713        "pattern": False,
2714        "ordinality": False,
2715        "when": False,
2716        "only": False,
2717    }
2718
2719    @property
2720    def name(self) -> str:
2721        if isinstance(self.this, Func):
2722            return ""
2723        return self.this.name
2724
2725    @property
2726    def db(self) -> str:
2727        return self.text("db")
2728
2729    @property
2730    def catalog(self) -> str:
2731        return self.text("catalog")
2732
2733    @property
2734    def selects(self) -> t.List[Expression]:
2735        return []
2736
2737    @property
2738    def named_selects(self) -> t.List[str]:
2739        return []
2740
2741    @property
2742    def parts(self) -> t.List[Expression]:
2743        """Return the parts of a table in order catalog, db, table."""
2744        parts: t.List[Expression] = []
2745
2746        for arg in ("catalog", "db", "this"):
2747            part = self.args.get(arg)
2748
2749            if isinstance(part, Dot):
2750                parts.extend(part.flatten())
2751            elif isinstance(part, Expression):
2752                parts.append(part)
2753
2754        return parts
2755
2756    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2757        parts = self.parts
2758        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2759        alias = self.args.get("alias")
2760        if alias:
2761            col = alias_(col, alias.this, copy=copy)
2762        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
2719    @property
2720    def name(self) -> str:
2721        if isinstance(self.this, Func):
2722            return ""
2723        return self.this.name
db: str
2725    @property
2726    def db(self) -> str:
2727        return self.text("db")
catalog: str
2729    @property
2730    def catalog(self) -> str:
2731        return self.text("catalog")
selects: List[Expression]
2733    @property
2734    def selects(self) -> t.List[Expression]:
2735        return []
named_selects: List[str]
2737    @property
2738    def named_selects(self) -> t.List[str]:
2739        return []
parts: List[Expression]
2741    @property
2742    def parts(self) -> t.List[Expression]:
2743        """Return the parts of a table in order catalog, db, table."""
2744        parts: t.List[Expression] = []
2745
2746        for arg in ("catalog", "db", "this"):
2747            part = self.args.get(arg)
2748
2749            if isinstance(part, Dot):
2750                parts.extend(part.flatten())
2751            elif isinstance(part, Expression):
2752                parts.append(part)
2753
2754        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
2794    @property
2795    def is_star(self) -> bool:
2796        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2798    @property
2799    def selects(self) -> t.List[Expression]:
2800        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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:
3088    def limit(
3089        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3090    ) -> Select:
3091        return _apply_builder(
3092            expression=expression,
3093            instance=self,
3094            arg="limit",
3095            into=Limit,
3096            prefix="LIMIT",
3097            dialect=dialect,
3098            copy=copy,
3099            into_arg="expression",
3100            **opts,
3101        )

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3527    @property
3528    def selects(self) -> t.List[Expression]:
3529        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3615class Pivot(Expression):
3616    arg_types = {
3617        "this": False,
3618        "alias": False,
3619        "expressions": False,
3620        "field": False,
3621        "unpivot": False,
3622        "using": False,
3623        "group": False,
3624        "columns": False,
3625        "include_nulls": False,
3626    }
3627
3628    @property
3629    def unpivot(self) -> bool:
3630        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
3628    @property
3629    def unpivot(self) -> bool:
3630        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3633class Window(Condition):
3634    arg_types = {
3635        "this": True,
3636        "partition_by": False,
3637        "order": False,
3638        "spec": False,
3639        "alias": False,
3640        "over": False,
3641        "first": False,
3642    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3645class WindowSpec(Expression):
3646    arg_types = {
3647        "kind": False,
3648        "start": False,
3649        "start_side": False,
3650        "end": False,
3651        "end_side": False,
3652    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3655class PreWhere(Expression):
3656    pass
key = 'prewhere'
class Where(Expression):
3659class Where(Expression):
3660    pass
key = 'where'
class Star(Expression):
3663class Star(Expression):
3664    arg_types = {"except": False, "replace": False}
3665
3666    @property
3667    def name(self) -> str:
3668        return "*"
3669
3670    @property
3671    def output_name(self) -> str:
3672        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3666    @property
3667    def name(self) -> str:
3668        return "*"
output_name: str
3670    @property
3671    def output_name(self) -> str:
3672        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):
3675class Parameter(Condition):
3676    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3679class SessionParameter(Condition):
3680    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3683class Placeholder(Condition):
3684    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3687class Null(Condition):
3688    arg_types: t.Dict[str, t.Any] = {}
3689
3690    @property
3691    def name(self) -> str:
3692        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3690    @property
3691    def name(self) -> str:
3692        return "NULL"
key = 'null'
class Boolean(Condition):
3695class Boolean(Condition):
3696    pass
key = 'boolean'
class DataTypeParam(Expression):
3699class DataTypeParam(Expression):
3700    arg_types = {"this": True, "expression": False}
3701
3702    @property
3703    def name(self) -> str:
3704        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3702    @property
3703    def name(self) -> str:
3704        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3707class DataType(Expression):
3708    arg_types = {
3709        "this": True,
3710        "expressions": False,
3711        "nested": False,
3712        "values": False,
3713        "prefix": False,
3714        "kind": False,
3715    }
3716
3717    class Type(AutoName):
3718        ARRAY = auto()
3719        AGGREGATEFUNCTION = auto()
3720        SIMPLEAGGREGATEFUNCTION = auto()
3721        BIGDECIMAL = auto()
3722        BIGINT = auto()
3723        BIGSERIAL = auto()
3724        BINARY = auto()
3725        BIT = auto()
3726        BOOLEAN = auto()
3727        BPCHAR = auto()
3728        CHAR = auto()
3729        DATE = auto()
3730        DATE32 = auto()
3731        DATEMULTIRANGE = auto()
3732        DATERANGE = auto()
3733        DATETIME = auto()
3734        DATETIME64 = auto()
3735        DECIMAL = auto()
3736        DOUBLE = auto()
3737        ENUM = auto()
3738        ENUM8 = auto()
3739        ENUM16 = auto()
3740        FIXEDSTRING = auto()
3741        FLOAT = auto()
3742        GEOGRAPHY = auto()
3743        GEOMETRY = auto()
3744        HLLSKETCH = auto()
3745        HSTORE = auto()
3746        IMAGE = auto()
3747        INET = auto()
3748        INT = auto()
3749        INT128 = auto()
3750        INT256 = auto()
3751        INT4MULTIRANGE = auto()
3752        INT4RANGE = auto()
3753        INT8MULTIRANGE = auto()
3754        INT8RANGE = auto()
3755        INTERVAL = auto()
3756        IPADDRESS = auto()
3757        IPPREFIX = auto()
3758        IPV4 = auto()
3759        IPV6 = auto()
3760        JSON = auto()
3761        JSONB = auto()
3762        LONGBLOB = auto()
3763        LONGTEXT = auto()
3764        LOWCARDINALITY = auto()
3765        MAP = auto()
3766        MEDIUMBLOB = auto()
3767        MEDIUMINT = auto()
3768        MEDIUMTEXT = auto()
3769        MONEY = auto()
3770        NCHAR = auto()
3771        NESTED = auto()
3772        NULL = auto()
3773        NULLABLE = auto()
3774        NUMMULTIRANGE = auto()
3775        NUMRANGE = auto()
3776        NVARCHAR = auto()
3777        OBJECT = auto()
3778        ROWVERSION = auto()
3779        SERIAL = auto()
3780        SET = auto()
3781        SMALLINT = auto()
3782        SMALLMONEY = auto()
3783        SMALLSERIAL = auto()
3784        STRUCT = auto()
3785        SUPER = auto()
3786        TEXT = auto()
3787        TINYBLOB = auto()
3788        TINYTEXT = auto()
3789        TIME = auto()
3790        TIMETZ = auto()
3791        TIMESTAMP = auto()
3792        TIMESTAMPLTZ = auto()
3793        TIMESTAMPTZ = auto()
3794        TIMESTAMP_S = auto()
3795        TIMESTAMP_MS = auto()
3796        TIMESTAMP_NS = auto()
3797        TINYINT = auto()
3798        TSMULTIRANGE = auto()
3799        TSRANGE = auto()
3800        TSTZMULTIRANGE = auto()
3801        TSTZRANGE = auto()
3802        UBIGINT = auto()
3803        UINT = auto()
3804        UINT128 = auto()
3805        UINT256 = auto()
3806        UMEDIUMINT = auto()
3807        UDECIMAL = auto()
3808        UNIQUEIDENTIFIER = auto()
3809        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3810        USERDEFINED = "USER-DEFINED"
3811        USMALLINT = auto()
3812        UTINYINT = auto()
3813        UUID = auto()
3814        VARBINARY = auto()
3815        VARCHAR = auto()
3816        VARIANT = auto()
3817        XML = auto()
3818        YEAR = auto()
3819
3820    TEXT_TYPES = {
3821        Type.CHAR,
3822        Type.NCHAR,
3823        Type.NVARCHAR,
3824        Type.TEXT,
3825        Type.VARCHAR,
3826    }
3827
3828    INTEGER_TYPES = {
3829        Type.BIGINT,
3830        Type.BIT,
3831        Type.INT,
3832        Type.INT128,
3833        Type.INT256,
3834        Type.MEDIUMINT,
3835        Type.SMALLINT,
3836        Type.TINYINT,
3837        Type.UBIGINT,
3838        Type.UINT,
3839        Type.UINT128,
3840        Type.UINT256,
3841        Type.UMEDIUMINT,
3842        Type.USMALLINT,
3843        Type.UTINYINT,
3844    }
3845
3846    FLOAT_TYPES = {
3847        Type.DOUBLE,
3848        Type.FLOAT,
3849    }
3850
3851    REAL_TYPES = {
3852        *FLOAT_TYPES,
3853        Type.BIGDECIMAL,
3854        Type.DECIMAL,
3855        Type.MONEY,
3856        Type.SMALLMONEY,
3857        Type.UDECIMAL,
3858    }
3859
3860    NUMERIC_TYPES = {
3861        *INTEGER_TYPES,
3862        *REAL_TYPES,
3863    }
3864
3865    TEMPORAL_TYPES = {
3866        Type.DATE,
3867        Type.DATE32,
3868        Type.DATETIME,
3869        Type.DATETIME64,
3870        Type.TIME,
3871        Type.TIMESTAMP,
3872        Type.TIMESTAMPLTZ,
3873        Type.TIMESTAMPTZ,
3874        Type.TIMESTAMP_MS,
3875        Type.TIMESTAMP_NS,
3876        Type.TIMESTAMP_S,
3877        Type.TIMETZ,
3878    }
3879
3880    @classmethod
3881    def build(
3882        cls,
3883        dtype: DATA_TYPE,
3884        dialect: DialectType = None,
3885        udt: bool = False,
3886        copy: bool = True,
3887        **kwargs,
3888    ) -> DataType:
3889        """
3890        Constructs a DataType object.
3891
3892        Args:
3893            dtype: the data type of interest.
3894            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3895            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3896                DataType, thus creating a user-defined type.
3897            copy: whether to copy the data type.
3898            kwargs: additional arguments to pass in the constructor of DataType.
3899
3900        Returns:
3901            The constructed DataType object.
3902        """
3903        from sqlglot import parse_one
3904
3905        if isinstance(dtype, str):
3906            if dtype.upper() == "UNKNOWN":
3907                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3908
3909            try:
3910                data_type_exp = parse_one(
3911                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3912                )
3913            except ParseError:
3914                if udt:
3915                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3916                raise
3917        elif isinstance(dtype, DataType.Type):
3918            data_type_exp = DataType(this=dtype)
3919        elif isinstance(dtype, DataType):
3920            return maybe_copy(dtype, copy)
3921        else:
3922            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3923
3924        return DataType(**{**data_type_exp.args, **kwargs})
3925
3926    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3927        """
3928        Checks whether this DataType matches one of the provided data types. Nested types or precision
3929        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3930
3931        Args:
3932            dtypes: the data types to compare this DataType to.
3933
3934        Returns:
3935            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3936        """
3937        for dtype in dtypes:
3938            other = DataType.build(dtype, copy=False, udt=True)
3939
3940            if (
3941                other.expressions
3942                or self.this == DataType.Type.USERDEFINED
3943                or other.this == DataType.Type.USERDEFINED
3944            ):
3945                matches = self == other
3946            else:
3947                matches = self.this == other.this
3948
3949            if matches:
3950                return True
3951        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>}
INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.INT128: 'INT128'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIT: 'BIT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.MONEY: 'MONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.FLOAT: 'FLOAT'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
TEMPORAL_TYPES = {<Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE32: 'DATE32'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME64: 'DATETIME64'>}
@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:
3880    @classmethod
3881    def build(
3882        cls,
3883        dtype: DATA_TYPE,
3884        dialect: DialectType = None,
3885        udt: bool = False,
3886        copy: bool = True,
3887        **kwargs,
3888    ) -> DataType:
3889        """
3890        Constructs a DataType object.
3891
3892        Args:
3893            dtype: the data type of interest.
3894            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3895            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3896                DataType, thus creating a user-defined type.
3897            copy: whether to copy the data type.
3898            kwargs: additional arguments to pass in the constructor of DataType.
3899
3900        Returns:
3901            The constructed DataType object.
3902        """
3903        from sqlglot import parse_one
3904
3905        if isinstance(dtype, str):
3906            if dtype.upper() == "UNKNOWN":
3907                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3908
3909            try:
3910                data_type_exp = parse_one(
3911                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3912                )
3913            except ParseError:
3914                if udt:
3915                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3916                raise
3917        elif isinstance(dtype, DataType.Type):
3918            data_type_exp = DataType(this=dtype)
3919        elif isinstance(dtype, DataType):
3920            return maybe_copy(dtype, copy)
3921        else:
3922            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3923
3924        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:
3926    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3927        """
3928        Checks whether this DataType matches one of the provided data types. Nested types or precision
3929        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3930
3931        Args:
3932            dtypes: the data types to compare this DataType to.
3933
3934        Returns:
3935            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3936        """
3937        for dtype in dtypes:
3938            other = DataType.build(dtype, copy=False, udt=True)
3939
3940            if (
3941                other.expressions
3942                or self.this == DataType.Type.USERDEFINED
3943                or other.this == DataType.Type.USERDEFINED
3944            ):
3945                matches = self == other
3946            else:
3947                matches = self.this == other.this
3948
3949            if matches:
3950                return True
3951        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):
3717    class Type(AutoName):
3718        ARRAY = auto()
3719        AGGREGATEFUNCTION = auto()
3720        SIMPLEAGGREGATEFUNCTION = auto()
3721        BIGDECIMAL = auto()
3722        BIGINT = auto()
3723        BIGSERIAL = auto()
3724        BINARY = auto()
3725        BIT = auto()
3726        BOOLEAN = auto()
3727        BPCHAR = auto()
3728        CHAR = auto()
3729        DATE = auto()
3730        DATE32 = auto()
3731        DATEMULTIRANGE = auto()
3732        DATERANGE = auto()
3733        DATETIME = auto()
3734        DATETIME64 = auto()
3735        DECIMAL = auto()
3736        DOUBLE = auto()
3737        ENUM = auto()
3738        ENUM8 = auto()
3739        ENUM16 = auto()
3740        FIXEDSTRING = auto()
3741        FLOAT = auto()
3742        GEOGRAPHY = auto()
3743        GEOMETRY = auto()
3744        HLLSKETCH = auto()
3745        HSTORE = auto()
3746        IMAGE = auto()
3747        INET = auto()
3748        INT = auto()
3749        INT128 = auto()
3750        INT256 = auto()
3751        INT4MULTIRANGE = auto()
3752        INT4RANGE = auto()
3753        INT8MULTIRANGE = auto()
3754        INT8RANGE = auto()
3755        INTERVAL = auto()
3756        IPADDRESS = auto()
3757        IPPREFIX = auto()
3758        IPV4 = auto()
3759        IPV6 = auto()
3760        JSON = auto()
3761        JSONB = auto()
3762        LONGBLOB = auto()
3763        LONGTEXT = auto()
3764        LOWCARDINALITY = auto()
3765        MAP = auto()
3766        MEDIUMBLOB = auto()
3767        MEDIUMINT = auto()
3768        MEDIUMTEXT = auto()
3769        MONEY = auto()
3770        NCHAR = auto()
3771        NESTED = auto()
3772        NULL = auto()
3773        NULLABLE = auto()
3774        NUMMULTIRANGE = auto()
3775        NUMRANGE = auto()
3776        NVARCHAR = auto()
3777        OBJECT = auto()
3778        ROWVERSION = auto()
3779        SERIAL = auto()
3780        SET = auto()
3781        SMALLINT = auto()
3782        SMALLMONEY = auto()
3783        SMALLSERIAL = auto()
3784        STRUCT = auto()
3785        SUPER = auto()
3786        TEXT = auto()
3787        TINYBLOB = auto()
3788        TINYTEXT = auto()
3789        TIME = auto()
3790        TIMETZ = auto()
3791        TIMESTAMP = auto()
3792        TIMESTAMPLTZ = auto()
3793        TIMESTAMPTZ = auto()
3794        TIMESTAMP_S = auto()
3795        TIMESTAMP_MS = auto()
3796        TIMESTAMP_NS = auto()
3797        TINYINT = auto()
3798        TSMULTIRANGE = auto()
3799        TSRANGE = auto()
3800        TSTZMULTIRANGE = auto()
3801        TSTZRANGE = auto()
3802        UBIGINT = auto()
3803        UINT = auto()
3804        UINT128 = auto()
3805        UINT256 = auto()
3806        UMEDIUMINT = auto()
3807        UDECIMAL = auto()
3808        UNIQUEIDENTIFIER = auto()
3809        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3810        USERDEFINED = "USER-DEFINED"
3811        USMALLINT = auto()
3812        UTINYINT = auto()
3813        UUID = auto()
3814        VARBINARY = auto()
3815        VARCHAR = auto()
3816        VARIANT = auto()
3817        XML = auto()
3818        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
3958class PseudoType(DataType):
3959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3963class ObjectIdentifier(DataType):
3964    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3968class SubqueryPredicate(Predicate):
3969    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3972class All(SubqueryPredicate):
3973    pass
key = 'all'
class Any(SubqueryPredicate):
3976class Any(SubqueryPredicate):
3977    pass
key = 'any'
class Exists(SubqueryPredicate):
3980class Exists(SubqueryPredicate):
3981    pass
key = 'exists'
class Command(Expression):
3986class Command(Expression):
3987    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3990class Transaction(Expression):
3991    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3994class Commit(Expression):
3995    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3998class Rollback(Expression):
3999    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4002class AlterTable(Expression):
4003    arg_types = {
4004        "this": True,
4005        "actions": True,
4006        "exists": False,
4007        "only": False,
4008        "options": False,
4009    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4012class AddConstraint(Expression):
4013    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4016class DropPartition(Expression):
4017    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4021class Binary(Condition):
4022    arg_types = {"this": True, "expression": True}
4023
4024    @property
4025    def left(self) -> Expression:
4026        return self.this
4027
4028    @property
4029    def right(self) -> Expression:
4030        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4024    @property
4025    def left(self) -> Expression:
4026        return self.this
right: Expression
4028    @property
4029    def right(self) -> Expression:
4030        return self.expression
key = 'binary'
class Add(Binary):
4033class Add(Binary):
4034    pass
key = 'add'
class Connector(Binary):
4037class Connector(Binary):
4038    pass
key = 'connector'
class And(Connector):
4041class And(Connector):
4042    pass
key = 'and'
class Or(Connector):
4045class Or(Connector):
4046    pass
key = 'or'
class BitwiseAnd(Binary):
4049class BitwiseAnd(Binary):
4050    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4053class BitwiseLeftShift(Binary):
4054    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4057class BitwiseOr(Binary):
4058    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4061class BitwiseRightShift(Binary):
4062    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4065class BitwiseXor(Binary):
4066    pass
key = 'bitwisexor'
class Div(Binary):
4069class Div(Binary):
4070    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):
4073class Overlaps(Binary):
4074    pass
key = 'overlaps'
class Dot(Binary):
4077class Dot(Binary):
4078    @property
4079    def is_star(self) -> bool:
4080        return self.expression.is_star
4081
4082    @property
4083    def name(self) -> str:
4084        return self.expression.name
4085
4086    @property
4087    def output_name(self) -> str:
4088        return self.name
4089
4090    @classmethod
4091    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4092        """Build a Dot object with a sequence of expressions."""
4093        if len(expressions) < 2:
4094            raise ValueError("Dot requires >= 2 expressions.")
4095
4096        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4097
4098    @property
4099    def parts(self) -> t.List[Expression]:
4100        """Return the parts of a table / column in order catalog, db, table."""
4101        this, *parts = self.flatten()
4102
4103        parts.reverse()
4104
4105        for arg in ("this", "table", "db", "catalog"):
4106            part = this.args.get(arg)
4107
4108            if isinstance(part, Expression):
4109                parts.append(part)
4110
4111        parts.reverse()
4112        return parts
is_star: bool
4078    @property
4079    def is_star(self) -> bool:
4080        return self.expression.is_star

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4115class DPipe(Binary):
4116    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4119class EQ(Binary, Predicate):
4120    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4123class NullSafeEQ(Binary, Predicate):
4124    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4127class NullSafeNEQ(Binary, Predicate):
4128    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4132class PropertyEQ(Binary):
4133    pass
key = 'propertyeq'
class Distance(Binary):
4136class Distance(Binary):
4137    pass
key = 'distance'
class Escape(Binary):
4140class Escape(Binary):
4141    pass
key = 'escape'
class Glob(Binary, Predicate):
4144class Glob(Binary, Predicate):
4145    pass
key = 'glob'
class GT(Binary, Predicate):
4148class GT(Binary, Predicate):
4149    pass
key = 'gt'
class GTE(Binary, Predicate):
4152class GTE(Binary, Predicate):
4153    pass
key = 'gte'
class ILike(Binary, Predicate):
4156class ILike(Binary, Predicate):
4157    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4160class ILikeAny(Binary, Predicate):
4161    pass
key = 'ilikeany'
class IntDiv(Binary):
4164class IntDiv(Binary):
4165    pass
key = 'intdiv'
class Is(Binary, Predicate):
4168class Is(Binary, Predicate):
4169    pass
key = 'is'
class Kwarg(Binary):
4172class Kwarg(Binary):
4173    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4176class Like(Binary, Predicate):
4177    pass
key = 'like'
class LikeAny(Binary, Predicate):
4180class LikeAny(Binary, Predicate):
4181    pass
key = 'likeany'
class LT(Binary, Predicate):
4184class LT(Binary, Predicate):
4185    pass
key = 'lt'
class LTE(Binary, Predicate):
4188class LTE(Binary, Predicate):
4189    pass
key = 'lte'
class Mod(Binary):
4192class Mod(Binary):
4193    pass
key = 'mod'
class Mul(Binary):
4196class Mul(Binary):
4197    pass
key = 'mul'
class NEQ(Binary, Predicate):
4200class NEQ(Binary, Predicate):
4201    pass
key = 'neq'
class Operator(Binary):
4205class Operator(Binary):
4206    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4209class SimilarTo(Binary, Predicate):
4210    pass
key = 'similarto'
class Slice(Binary):
4213class Slice(Binary):
4214    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4217class Sub(Binary):
4218    pass
key = 'sub'
class Unary(Condition):
4223class Unary(Condition):
4224    pass
key = 'unary'
class BitwiseNot(Unary):
4227class BitwiseNot(Unary):
4228    pass
key = 'bitwisenot'
class Not(Unary):
4231class Not(Unary):
4232    pass
key = 'not'
class Paren(Unary):
4235class Paren(Unary):
4236    arg_types = {"this": True, "with": False}
4237
4238    @property
4239    def output_name(self) -> str:
4240        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4238    @property
4239    def output_name(self) -> str:
4240        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):
4243class Neg(Unary):
4244    pass
key = 'neg'
class Alias(Expression):
4247class Alias(Expression):
4248    arg_types = {"this": True, "alias": False}
4249
4250    @property
4251    def output_name(self) -> str:
4252        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4250    @property
4251    def output_name(self) -> str:
4252        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):
4257class PivotAlias(Alias):
4258    pass
key = 'pivotalias'
class Aliases(Expression):
4261class Aliases(Expression):
4262    arg_types = {"this": True, "expressions": True}
4263
4264    @property
4265    def aliases(self):
4266        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4264    @property
4265    def aliases(self):
4266        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4270class AtIndex(Expression):
4271    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4274class AtTimeZone(Expression):
4275    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4278class FromTimeZone(Expression):
4279    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4282class Between(Predicate):
4283    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4286class Bracket(Condition):
4287    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4288    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4289
4290    @property
4291    def output_name(self) -> str:
4292        if len(self.expressions) == 1:
4293            return self.expressions[0].output_name
4294
4295        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4290    @property
4291    def output_name(self) -> str:
4292        if len(self.expressions) == 1:
4293            return self.expressions[0].output_name
4294
4295        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):
4298class Distinct(Expression):
4299    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4302class In(Predicate):
4303    arg_types = {
4304        "this": True,
4305        "expressions": False,
4306        "query": False,
4307        "unnest": False,
4308        "field": False,
4309        "is_global": False,
4310    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4314class ForIn(Expression):
4315    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4318class TimeUnit(Expression):
4319    """Automatically converts unit arg into a var."""
4320
4321    arg_types = {"unit": False}
4322
4323    UNABBREVIATED_UNIT_NAME = {
4324        "D": "DAY",
4325        "H": "HOUR",
4326        "M": "MINUTE",
4327        "MS": "MILLISECOND",
4328        "NS": "NANOSECOND",
4329        "Q": "QUARTER",
4330        "S": "SECOND",
4331        "US": "MICROSECOND",
4332        "W": "WEEK",
4333        "Y": "YEAR",
4334    }
4335
4336    VAR_LIKE = (Column, Literal, Var)
4337
4338    def __init__(self, **args):
4339        unit = args.get("unit")
4340        if isinstance(unit, self.VAR_LIKE):
4341            args["unit"] = Var(
4342                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4343            )
4344        elif isinstance(unit, Week):
4345            unit.set("this", Var(this=unit.this.name.upper()))
4346
4347        super().__init__(**args)
4348
4349    @property
4350    def unit(self) -> t.Optional[Var]:
4351        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4338    def __init__(self, **args):
4339        unit = args.get("unit")
4340        if isinstance(unit, self.VAR_LIKE):
4341            args["unit"] = Var(
4342                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4343            )
4344        elif isinstance(unit, Week):
4345            unit.set("this", Var(this=unit.this.name.upper()))
4346
4347        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]
4349    @property
4350    def unit(self) -> t.Optional[Var]:
4351        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4354class IntervalOp(TimeUnit):
4355    arg_types = {"unit": True, "expression": True}
4356
4357    def interval(self):
4358        return Interval(
4359            this=self.expression.copy(),
4360            unit=self.unit.copy(),
4361        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4357    def interval(self):
4358        return Interval(
4359            this=self.expression.copy(),
4360            unit=self.unit.copy(),
4361        )
key = 'intervalop'
class IntervalSpan(DataType):
4367class IntervalSpan(DataType):
4368    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4371class Interval(TimeUnit):
4372    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4375class IgnoreNulls(Expression):
4376    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4379class RespectNulls(Expression):
4380    pass
key = 'respectnulls'
class HavingMax(Expression):
4384class HavingMax(Expression):
4385    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4389class Func(Condition):
4390    """
4391    The base class for all function expressions.
4392
4393    Attributes:
4394        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4395            treated as a variable length argument and the argument's value will be stored as a list.
4396        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4397            function expression. These values are used to map this node to a name during parsing as
4398            well as to provide the function's name during SQL string generation. By default the SQL
4399            name is set to the expression's class name transformed to snake case.
4400    """
4401
4402    is_var_len_args = False
4403
4404    @classmethod
4405    def from_arg_list(cls, args):
4406        if cls.is_var_len_args:
4407            all_arg_keys = list(cls.arg_types)
4408            # If this function supports variable length argument treat the last argument as such.
4409            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4410            num_non_var = len(non_var_len_arg_keys)
4411
4412            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4413            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4414        else:
4415            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4416
4417        return cls(**args_dict)
4418
4419    @classmethod
4420    def sql_names(cls):
4421        if cls is Func:
4422            raise NotImplementedError(
4423                "SQL name is only supported by concrete function implementations"
4424            )
4425        if "_sql_names" not in cls.__dict__:
4426            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4427        return cls._sql_names
4428
4429    @classmethod
4430    def sql_name(cls):
4431        return cls.sql_names()[0]
4432
4433    @classmethod
4434    def default_parser_mappings(cls):
4435        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):
4404    @classmethod
4405    def from_arg_list(cls, args):
4406        if cls.is_var_len_args:
4407            all_arg_keys = list(cls.arg_types)
4408            # If this function supports variable length argument treat the last argument as such.
4409            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4410            num_non_var = len(non_var_len_arg_keys)
4411
4412            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4413            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4414        else:
4415            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4416
4417        return cls(**args_dict)
@classmethod
def sql_names(cls):
4419    @classmethod
4420    def sql_names(cls):
4421        if cls is Func:
4422            raise NotImplementedError(
4423                "SQL name is only supported by concrete function implementations"
4424            )
4425        if "_sql_names" not in cls.__dict__:
4426            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4427        return cls._sql_names
@classmethod
def sql_name(cls):
4429    @classmethod
4430    def sql_name(cls):
4431        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4433    @classmethod
4434    def default_parser_mappings(cls):
4435        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4438class AggFunc(Func):
4439    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4442class ParameterizedAgg(AggFunc):
4443    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4446class Abs(Func):
4447    pass
key = 'abs'
class ArgMax(AggFunc):
4450class ArgMax(AggFunc):
4451    arg_types = {"this": True, "expression": True, "count": False}
4452    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4455class ArgMin(AggFunc):
4456    arg_types = {"this": True, "expression": True, "count": False}
4457    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4460class ApproxTopK(AggFunc):
4461    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4464class Flatten(Func):
4465    pass
key = 'flatten'
class Transform(Func):
4469class Transform(Func):
4470    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4473class Anonymous(Func):
4474    arg_types = {"this": True, "expressions": False}
4475    is_var_len_args = True
4476
4477    @property
4478    def name(self) -> str:
4479        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
4477    @property
4478    def name(self) -> str:
4479        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4482class AnonymousAggFunc(AggFunc):
4483    arg_types = {"this": True, "expressions": False}
4484    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4488class CombinedAggFunc(AnonymousAggFunc):
4489    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4492class CombinedParameterizedAgg(ParameterizedAgg):
4493    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):
4498class Hll(AggFunc):
4499    arg_types = {"this": True, "expressions": False}
4500    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4503class ApproxDistinct(AggFunc):
4504    arg_types = {"this": True, "accuracy": False}
4505    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4508class Array(Func):
4509    arg_types = {"expressions": False}
4510    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4514class ToArray(Func):
4515    pass
key = 'toarray'
class ToChar(Func):
4520class ToChar(Func):
4521    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class Convert(Func):
4525class Convert(Func):
4526    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4529class GenerateSeries(Func):
4530    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):
4533class ArrayAgg(AggFunc):
4534    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4537class ArrayUniqueAgg(AggFunc):
4538    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4541class ArrayAll(Func):
4542    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4546class ArrayAny(Func):
4547    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4550class ArrayConcat(Func):
4551    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4552    arg_types = {"this": True, "expressions": False}
4553    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4556class ArrayContains(Binary, Func):
4557    pass
key = 'arraycontains'
class ArrayContained(Binary):
4560class ArrayContained(Binary):
4561    pass
key = 'arraycontained'
class ArrayFilter(Func):
4564class ArrayFilter(Func):
4565    arg_types = {"this": True, "expression": True}
4566    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4569class ArrayJoin(Func):
4570    arg_types = {"this": True, "expression": True, "null": False}
4571    _sql_names = ["ARRAY_JOIN", "ARRAY_TO_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArrayOverlaps(Binary, Func):
4574class ArrayOverlaps(Binary, Func):
4575    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4578class ArraySize(Func):
4579    arg_types = {"this": True, "expression": False}
4580    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4583class ArraySort(Func):
4584    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4587class ArraySum(Func):
4588    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4591class ArrayUnionAgg(AggFunc):
4592    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4595class Avg(AggFunc):
4596    pass
key = 'avg'
class AnyValue(AggFunc):
4599class AnyValue(AggFunc):
4600    pass
key = 'anyvalue'
class Lag(AggFunc):
4603class Lag(AggFunc):
4604    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4607class Lead(AggFunc):
4608    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4613class First(AggFunc):
4614    pass
key = 'first'
class Last(AggFunc):
4617class Last(AggFunc):
4618    pass
key = 'last'
class FirstValue(AggFunc):
4621class FirstValue(AggFunc):
4622    pass
key = 'firstvalue'
class LastValue(AggFunc):
4625class LastValue(AggFunc):
4626    pass
key = 'lastvalue'
class NthValue(AggFunc):
4629class NthValue(AggFunc):
4630    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4633class Case(Func):
4634    arg_types = {"this": False, "ifs": True, "default": False}
4635
4636    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4637        instance = maybe_copy(self, copy)
4638        instance.append(
4639            "ifs",
4640            If(
4641                this=maybe_parse(condition, copy=copy, **opts),
4642                true=maybe_parse(then, copy=copy, **opts),
4643            ),
4644        )
4645        return instance
4646
4647    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4648        instance = maybe_copy(self, copy)
4649        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4650        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:
4636    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4637        instance = maybe_copy(self, copy)
4638        instance.append(
4639            "ifs",
4640            If(
4641                this=maybe_parse(condition, copy=copy, **opts),
4642                true=maybe_parse(then, copy=copy, **opts),
4643            ),
4644        )
4645        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4647    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4648        instance = maybe_copy(self, copy)
4649        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4650        return instance
key = 'case'
class Cast(Func):
4653class Cast(Func):
4654    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4655
4656    @property
4657    def name(self) -> str:
4658        return self.this.name
4659
4660    @property
4661    def to(self) -> DataType:
4662        return self.args["to"]
4663
4664    @property
4665    def output_name(self) -> str:
4666        return self.name
4667
4668    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4669        """
4670        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4671        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4672        array<int> != array<float>.
4673
4674        Args:
4675            dtypes: the data types to compare this Cast's DataType to.
4676
4677        Returns:
4678            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4679        """
4680        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4656    @property
4657    def name(self) -> str:
4658        return self.this.name
to: DataType
4660    @property
4661    def to(self) -> DataType:
4662        return self.args["to"]
output_name: str
4664    @property
4665    def output_name(self) -> str:
4666        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:
4668    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4669        """
4670        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4671        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4672        array<int> != array<float>.
4673
4674        Args:
4675            dtypes: the data types to compare this Cast's DataType to.
4676
4677        Returns:
4678            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4679        """
4680        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):
4683class TryCast(Cast):
4684    pass
key = 'trycast'
class CastToStrType(Func):
4687class CastToStrType(Func):
4688    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4691class Collate(Binary, Func):
4692    pass
key = 'collate'
class Ceil(Func):
4695class Ceil(Func):
4696    arg_types = {"this": True, "decimals": False}
4697    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4700class Coalesce(Func):
4701    arg_types = {"this": True, "expressions": False}
4702    is_var_len_args = True
4703    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4706class Chr(Func):
4707    arg_types = {"this": True, "charset": False, "expressions": False}
4708    is_var_len_args = True
4709    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4712class Concat(Func):
4713    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4714    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4717class ConcatWs(Concat):
4718    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4722class ConnectByRoot(Func):
4723    pass
key = 'connectbyroot'
class Count(AggFunc):
4726class Count(AggFunc):
4727    arg_types = {"this": False, "expressions": False}
4728    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4731class CountIf(AggFunc):
4732    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4736class Cbrt(Func):
4737    pass
key = 'cbrt'
class CurrentDate(Func):
4740class CurrentDate(Func):
4741    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4744class CurrentDatetime(Func):
4745    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4748class CurrentTime(Func):
4749    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4752class CurrentTimestamp(Func):
4753    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4756class CurrentUser(Func):
4757    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4760class DateAdd(Func, IntervalOp):
4761    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4764class DateSub(Func, IntervalOp):
4765    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4768class DateDiff(Func, TimeUnit):
4769    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4770    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4773class DateTrunc(Func):
4774    arg_types = {"unit": True, "this": True, "zone": False}
4775
4776    def __init__(self, **args):
4777        unit = args.get("unit")
4778        if isinstance(unit, TimeUnit.VAR_LIKE):
4779            args["unit"] = Literal.string(
4780                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4781            )
4782        elif isinstance(unit, Week):
4783            unit.set("this", Literal.string(unit.this.name.upper()))
4784
4785        super().__init__(**args)
4786
4787    @property
4788    def unit(self) -> Expression:
4789        return self.args["unit"]
DateTrunc(**args)
4776    def __init__(self, **args):
4777        unit = args.get("unit")
4778        if isinstance(unit, TimeUnit.VAR_LIKE):
4779            args["unit"] = Literal.string(
4780                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4781            )
4782        elif isinstance(unit, Week):
4783            unit.set("this", Literal.string(unit.this.name.upper()))
4784
4785        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4787    @property
4788    def unit(self) -> Expression:
4789        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4792class DatetimeAdd(Func, IntervalOp):
4793    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4796class DatetimeSub(Func, IntervalOp):
4797    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4800class DatetimeDiff(Func, TimeUnit):
4801    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4804class DatetimeTrunc(Func, TimeUnit):
4805    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4808class DayOfWeek(Func):
4809    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4812class DayOfMonth(Func):
4813    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4816class DayOfYear(Func):
4817    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4820class ToDays(Func):
4821    pass
key = 'todays'
class WeekOfYear(Func):
4824class WeekOfYear(Func):
4825    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4828class MonthsBetween(Func):
4829    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4832class LastDay(Func, TimeUnit):
4833    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4834    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4837class Extract(Func):
4838    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4841class Timestamp(Func):
4842    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4845class TimestampAdd(Func, TimeUnit):
4846    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4849class TimestampSub(Func, TimeUnit):
4850    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4853class TimestampDiff(Func, TimeUnit):
4854    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4855    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4858class TimestampTrunc(Func, TimeUnit):
4859    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4862class TimeAdd(Func, TimeUnit):
4863    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4866class TimeSub(Func, TimeUnit):
4867    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4870class TimeDiff(Func, TimeUnit):
4871    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4874class TimeTrunc(Func, TimeUnit):
4875    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4878class DateFromParts(Func):
4879    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4880    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4883class TimeFromParts(Func):
4884    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4885    arg_types = {
4886        "hour": True,
4887        "min": True,
4888        "sec": True,
4889        "nano": False,
4890        "fractions": False,
4891        "precision": False,
4892    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4895class DateStrToDate(Func):
4896    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4899class DateToDateStr(Func):
4900    pass
key = 'datetodatestr'
class DateToDi(Func):
4903class DateToDi(Func):
4904    pass
key = 'datetodi'
class Date(Func):
4908class Date(Func):
4909    arg_types = {"this": False, "zone": False, "expressions": False}
4910    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4913class Day(Func):
4914    pass
key = 'day'
class Decode(Func):
4917class Decode(Func):
4918    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4921class DiToDate(Func):
4922    pass
key = 'ditodate'
class Encode(Func):
4925class Encode(Func):
4926    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4929class Exp(Func):
4930    pass
key = 'exp'
class Explode(Func):
4934class Explode(Func):
4935    arg_types = {"this": True, "expressions": False}
4936    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4939class ExplodeOuter(Explode):
4940    pass
key = 'explodeouter'
class Posexplode(Explode):
4943class Posexplode(Explode):
4944    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
4947class PosexplodeOuter(Posexplode, ExplodeOuter):
4948    pass
key = 'posexplodeouter'
class Floor(Func):
4951class Floor(Func):
4952    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4955class FromBase64(Func):
4956    pass
key = 'frombase64'
class ToBase64(Func):
4959class ToBase64(Func):
4960    pass
key = 'tobase64'
class Greatest(Func):
4963class Greatest(Func):
4964    arg_types = {"this": True, "expressions": False}
4965    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4968class GroupConcat(AggFunc):
4969    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4972class Hex(Func):
4973    pass
key = 'hex'
class Xor(Connector, Func):
4976class Xor(Connector, Func):
4977    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4980class If(Func):
4981    arg_types = {"this": True, "true": True, "false": False}
4982    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4985class Nullif(Func):
4986    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4989class Initcap(Func):
4990    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4993class IsNan(Func):
4994    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4997class IsInf(Func):
4998    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5001class JSONPath(Expression):
5002    arg_types = {"expressions": True}
5003
5004    @property
5005    def output_name(self) -> str:
5006        last_segment = self.expressions[-1].this
5007        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5004    @property
5005    def output_name(self) -> str:
5006        last_segment = self.expressions[-1].this
5007        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):
5010class JSONPathPart(Expression):
5011    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5014class JSONPathFilter(JSONPathPart):
5015    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5018class JSONPathKey(JSONPathPart):
5019    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5022class JSONPathRecursive(JSONPathPart):
5023    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5026class JSONPathRoot(JSONPathPart):
5027    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5030class JSONPathScript(JSONPathPart):
5031    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5034class JSONPathSlice(JSONPathPart):
5035    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5038class JSONPathSelector(JSONPathPart):
5039    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5042class JSONPathSubscript(JSONPathPart):
5043    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5046class JSONPathUnion(JSONPathPart):
5047    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5050class JSONPathWildcard(JSONPathPart):
5051    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5054class FormatJson(Expression):
5055    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5058class JSONKeyValue(Expression):
5059    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5062class JSONObject(Func):
5063    arg_types = {
5064        "expressions": False,
5065        "null_handling": False,
5066        "unique_keys": False,
5067        "return_type": False,
5068        "encoding": False,
5069    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5072class JSONObjectAgg(AggFunc):
5073    arg_types = {
5074        "expressions": False,
5075        "null_handling": False,
5076        "unique_keys": False,
5077        "return_type": False,
5078        "encoding": False,
5079    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5083class JSONArray(Func):
5084    arg_types = {
5085        "expressions": True,
5086        "null_handling": False,
5087        "return_type": False,
5088        "strict": False,
5089    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5093class JSONArrayAgg(Func):
5094    arg_types = {
5095        "this": True,
5096        "order": False,
5097        "null_handling": False,
5098        "return_type": False,
5099        "strict": False,
5100    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5105class JSONColumnDef(Expression):
5106    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):
5109class JSONSchema(Expression):
5110    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5114class JSONTable(Func):
5115    arg_types = {
5116        "this": True,
5117        "schema": True,
5118        "path": False,
5119        "error_handling": False,
5120        "empty_handling": False,
5121    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5124class OpenJSONColumnDef(Expression):
5125    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):
5128class OpenJSON(Func):
5129    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5132class JSONBContains(Binary):
5133    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5136class JSONExtract(Binary, Func):
5137    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5138    _sql_names = ["JSON_EXTRACT"]
5139    is_var_len_args = True
5140
5141    @property
5142    def output_name(self) -> str:
5143        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
5141    @property
5142    def output_name(self) -> str:
5143        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):
5146class JSONExtractScalar(Binary, Func):
5147    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5148    _sql_names = ["JSON_EXTRACT_SCALAR"]
5149    is_var_len_args = True
5150
5151    @property
5152    def output_name(self) -> str:
5153        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
5151    @property
5152    def output_name(self) -> str:
5153        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):
5156class JSONBExtract(Binary, Func):
5157    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5160class JSONBExtractScalar(Binary, Func):
5161    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5164class JSONFormat(Func):
5165    arg_types = {"this": False, "options": False}
5166    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5170class JSONArrayContains(Binary, Predicate, Func):
5171    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5174class ParseJSON(Func):
5175    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5176    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5177    arg_types = {"this": True, "expressions": False}
5178    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5181class Least(Func):
5182    arg_types = {"this": True, "expressions": False}
5183    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5186class Left(Func):
5187    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5194class Length(Func):
5195    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5198class Levenshtein(Func):
5199    arg_types = {
5200        "this": True,
5201        "expression": False,
5202        "ins_cost": False,
5203        "del_cost": False,
5204        "sub_cost": False,
5205    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5208class Ln(Func):
5209    pass
key = 'ln'
class Log(Func):
5212class Log(Func):
5213    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5216class Log2(Func):
5217    pass
key = 'log2'
class Log10(Func):
5220class Log10(Func):
5221    pass
key = 'log10'
class LogicalOr(AggFunc):
5224class LogicalOr(AggFunc):
5225    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5228class LogicalAnd(AggFunc):
5229    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5232class Lower(Func):
5233    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5236class Map(Func):
5237    arg_types = {"keys": False, "values": False}
5238
5239    @property
5240    def keys(self) -> t.List[Expression]:
5241        keys = self.args.get("keys")
5242        return keys.expressions if keys else []
5243
5244    @property
5245    def values(self) -> t.List[Expression]:
5246        values = self.args.get("values")
5247        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5239    @property
5240    def keys(self) -> t.List[Expression]:
5241        keys = self.args.get("keys")
5242        return keys.expressions if keys else []
values: List[Expression]
5244    @property
5245    def values(self) -> t.List[Expression]:
5246        values = self.args.get("values")
5247        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5250class MapFromEntries(Func):
5251    pass
key = 'mapfromentries'
class StarMap(Func):
5254class StarMap(Func):
5255    pass
key = 'starmap'
class VarMap(Func):
5258class VarMap(Func):
5259    arg_types = {"keys": True, "values": True}
5260    is_var_len_args = True
5261
5262    @property
5263    def keys(self) -> t.List[Expression]:
5264        return self.args["keys"].expressions
5265
5266    @property
5267    def values(self) -> t.List[Expression]:
5268        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5262    @property
5263    def keys(self) -> t.List[Expression]:
5264        return self.args["keys"].expressions
values: List[Expression]
5266    @property
5267    def values(self) -> t.List[Expression]:
5268        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5272class MatchAgainst(Func):
5273    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5276class Max(AggFunc):
5277    arg_types = {"this": True, "expressions": False}
5278    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5281class MD5(Func):
5282    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5286class MD5Digest(Func):
5287    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5290class Min(AggFunc):
5291    arg_types = {"this": True, "expressions": False}
5292    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5295class Month(Func):
5296    pass
key = 'month'
class AddMonths(Func):
5299class AddMonths(Func):
5300    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5303class Nvl2(Func):
5304    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5308class Predict(Func):
5309    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5312class Pow(Binary, Func):
5313    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5316class PercentileCont(AggFunc):
5317    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5320class PercentileDisc(AggFunc):
5321    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5324class Quantile(AggFunc):
5325    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5328class ApproxQuantile(Quantile):
5329    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):
5332class Rand(Func):
5333    _sql_names = ["RAND", "RANDOM"]
5334    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5337class Randn(Func):
5338    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5341class RangeN(Func):
5342    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5345class ReadCSV(Func):
5346    _sql_names = ["READ_CSV"]
5347    is_var_len_args = True
5348    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5351class Reduce(Func):
5352    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):
5355class RegexpExtract(Func):
5356    arg_types = {
5357        "this": True,
5358        "expression": True,
5359        "position": False,
5360        "occurrence": False,
5361        "parameters": False,
5362        "group": False,
5363    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5366class RegexpReplace(Func):
5367    arg_types = {
5368        "this": True,
5369        "expression": True,
5370        "replacement": False,
5371        "position": False,
5372        "occurrence": False,
5373        "parameters": False,
5374        "modifiers": False,
5375    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5378class RegexpLike(Binary, Func):
5379    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5382class RegexpILike(Binary, Func):
5383    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5388class RegexpSplit(Func):
5389    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5392class Repeat(Func):
5393    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5398class Round(Func):
5399    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5402class RowNumber(Func):
5403    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5406class SafeDivide(Func):
5407    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5410class SHA(Func):
5411    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5414class SHA2(Func):
5415    _sql_names = ["SHA2"]
5416    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5419class Sign(Func):
5420    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5423class SortArray(Func):
5424    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5427class Split(Func):
5428    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5433class Substring(Func):
5434    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5437class StandardHash(Func):
5438    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5441class StartsWith(Func):
5442    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5446class StrPosition(Func):
5447    arg_types = {
5448        "this": True,
5449        "substr": True,
5450        "position": False,
5451        "instance": False,
5452    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5455class StrToDate(Func):
5456    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5459class StrToTime(Func):
5460    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5465class StrToUnix(Func):
5466    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5471class StrToMap(Func):
5472    arg_types = {
5473        "this": True,
5474        "pair_delim": False,
5475        "key_value_delim": False,
5476        "duplicate_resolution_callback": False,
5477    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5480class NumberToStr(Func):
5481    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5484class FromBase(Func):
5485    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5488class Struct(Func):
5489    arg_types = {"expressions": False}
5490    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5493class StructExtract(Func):
5494    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5499class Stuff(Func):
5500    _sql_names = ["STUFF", "INSERT"]
5501    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):
5504class Sum(AggFunc):
5505    pass
key = 'sum'
class Sqrt(Func):
5508class Sqrt(Func):
5509    pass
key = 'sqrt'
class Stddev(AggFunc):
5512class Stddev(AggFunc):
5513    pass
key = 'stddev'
class StddevPop(AggFunc):
5516class StddevPop(AggFunc):
5517    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5520class StddevSamp(AggFunc):
5521    pass
key = 'stddevsamp'
class TimeToStr(Func):
5524class TimeToStr(Func):
5525    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5528class TimeToTimeStr(Func):
5529    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5532class TimeToUnix(Func):
5533    pass
key = 'timetounix'
class TimeStrToDate(Func):
5536class TimeStrToDate(Func):
5537    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5540class TimeStrToTime(Func):
5541    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5544class TimeStrToUnix(Func):
5545    pass
key = 'timestrtounix'
class Trim(Func):
5548class Trim(Func):
5549    arg_types = {
5550        "this": True,
5551        "expression": False,
5552        "position": False,
5553        "collation": False,
5554    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5557class TsOrDsAdd(Func, TimeUnit):
5558    # return_type is used to correctly cast the arguments of this expression when transpiling it
5559    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5560
5561    @property
5562    def return_type(self) -> DataType:
5563        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
5561    @property
5562    def return_type(self) -> DataType:
5563        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5566class TsOrDsDiff(Func, TimeUnit):
5567    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5570class TsOrDsToDateStr(Func):
5571    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5574class TsOrDsToDate(Func):
5575    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5578class TsOrDsToTime(Func):
5579    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5582class TsOrDiToDi(Func):
5583    pass
key = 'tsorditodi'
class Unhex(Func):
5586class Unhex(Func):
5587    pass
key = 'unhex'
class UnixDate(Func):
5591class UnixDate(Func):
5592    pass
key = 'unixdate'
class UnixToStr(Func):
5595class UnixToStr(Func):
5596    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5601class UnixToTime(Func):
5602    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5603
5604    SECONDS = Literal.number(0)
5605    DECIS = Literal.number(1)
5606    CENTIS = Literal.number(2)
5607    MILLIS = Literal.number(3)
5608    DECIMILLIS = Literal.number(4)
5609    CENTIMILLIS = Literal.number(5)
5610    MICROS = Literal.number(6)
5611    DECIMICROS = Literal.number(7)
5612    CENTIMICROS = Literal.number(8)
5613    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):
5616class UnixToTimeStr(Func):
5617    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5620class TimestampFromParts(Func):
5621    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5622    arg_types = {
5623        "year": True,
5624        "month": True,
5625        "day": True,
5626        "hour": True,
5627        "min": True,
5628        "sec": True,
5629        "nano": False,
5630        "zone": False,
5631        "milli": False,
5632    }
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):
5635class Upper(Func):
5636    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5639class Variance(AggFunc):
5640    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5643class VariancePop(AggFunc):
5644    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5647class Week(Func):
5648    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5651class XMLTable(Func):
5652    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):
5655class Year(Func):
5656    pass
key = 'year'
class Use(Expression):
5659class Use(Expression):
5660    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5663class Merge(Expression):
5664    arg_types = {
5665        "this": True,
5666        "using": True,
5667        "on": True,
5668        "expressions": True,
5669        "with": False,
5670    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5673class When(Func):
5674    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):
5679class NextValueFor(Func):
5680    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_TO_STRING': <class 'ArrayJoin'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5718def maybe_parse(
5719    sql_or_expression: ExpOrStr,
5720    *,
5721    into: t.Optional[IntoType] = None,
5722    dialect: DialectType = None,
5723    prefix: t.Optional[str] = None,
5724    copy: bool = False,
5725    **opts,
5726) -> Expression:
5727    """Gracefully handle a possible string or expression.
5728
5729    Example:
5730        >>> maybe_parse("1")
5731        Literal(this=1, is_string=False)
5732        >>> maybe_parse(to_identifier("x"))
5733        Identifier(this=x, quoted=False)
5734
5735    Args:
5736        sql_or_expression: the SQL code string or an expression
5737        into: the SQLGlot Expression to parse into
5738        dialect: the dialect used to parse the input expressions (in the case that an
5739            input expression is a SQL string).
5740        prefix: a string to prefix the sql with before it gets parsed
5741            (automatically includes a space)
5742        copy: whether to copy the expression.
5743        **opts: other options to use to parse the input expressions (again, in the case
5744            that an input expression is a SQL string).
5745
5746    Returns:
5747        Expression: the parsed or given expression.
5748    """
5749    if isinstance(sql_or_expression, Expression):
5750        if copy:
5751            return sql_or_expression.copy()
5752        return sql_or_expression
5753
5754    if sql_or_expression is None:
5755        raise ParseError("SQL cannot be None")
5756
5757    import sqlglot
5758
5759    sql = str(sql_or_expression)
5760    if prefix:
5761        sql = f"{prefix} {sql}"
5762
5763    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):
5774def maybe_copy(instance, copy=True):
5775    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:
5989def union(
5990    left: ExpOrStr,
5991    right: ExpOrStr,
5992    distinct: bool = True,
5993    dialect: DialectType = None,
5994    copy: bool = True,
5995    **opts,
5996) -> Union:
5997    """
5998    Initializes a syntax tree from one UNION expression.
5999
6000    Example:
6001        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6002        'SELECT * FROM foo UNION SELECT * FROM bla'
6003
6004    Args:
6005        left: the SQL code string corresponding to the left-hand side.
6006            If an `Expression` instance is passed, it will be used as-is.
6007        right: the SQL code string corresponding to the right-hand side.
6008            If an `Expression` instance is passed, it will be used as-is.
6009        distinct: set the DISTINCT flag if and only if this is true.
6010        dialect: the dialect used to parse the input expression.
6011        copy: whether to copy the expression.
6012        opts: other options to use to parse the input expressions.
6013
6014    Returns:
6015        The new Union instance.
6016    """
6017    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6018    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6019
6020    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:
6023def intersect(
6024    left: ExpOrStr,
6025    right: ExpOrStr,
6026    distinct: bool = True,
6027    dialect: DialectType = None,
6028    copy: bool = True,
6029    **opts,
6030) -> Intersect:
6031    """
6032    Initializes a syntax tree from one INTERSECT expression.
6033
6034    Example:
6035        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6036        'SELECT * FROM foo INTERSECT 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 Intersect 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 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:
6057def except_(
6058    left: ExpOrStr,
6059    right: ExpOrStr,
6060    distinct: bool = True,
6061    dialect: DialectType = None,
6062    copy: bool = True,
6063    **opts,
6064) -> Except:
6065    """
6066    Initializes a syntax tree from one EXCEPT expression.
6067
6068    Example:
6069        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6070        'SELECT * FROM foo EXCEPT 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 Except 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 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:
6091def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6092    """
6093    Initializes a syntax tree from one or multiple SELECT expressions.
6094
6095    Example:
6096        >>> select("col1", "col2").from_("tbl").sql()
6097        'SELECT col1, col2 FROM tbl'
6098
6099    Args:
6100        *expressions: the SQL code string to parse as the expressions of a
6101            SELECT statement. If an Expression instance is passed, this is used as-is.
6102        dialect: the dialect used to parse the input expressions (in the case that an
6103            input expression is a SQL string).
6104        **opts: other options to use to parse the input expressions (again, in the case
6105            that an input expression is a SQL string).
6106
6107    Returns:
6108        Select: the syntax tree for the SELECT statement.
6109    """
6110    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:
6113def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6114    """
6115    Initializes a syntax tree from a FROM expression.
6116
6117    Example:
6118        >>> from_("tbl").select("col1", "col2").sql()
6119        'SELECT col1, col2 FROM tbl'
6120
6121    Args:
6122        *expression: the SQL code string to parse as the FROM expressions of a
6123            SELECT statement. If an Expression instance is passed, this is used as-is.
6124        dialect: the dialect used to parse the input expression (in the case that the
6125            input expression is a SQL string).
6126        **opts: other options to use to parse the input expressions (again, in the case
6127            that the input expression is a SQL string).
6128
6129    Returns:
6130        Select: the syntax tree for the SELECT statement.
6131    """
6132    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:
6135def update(
6136    table: str | Table,
6137    properties: dict,
6138    where: t.Optional[ExpOrStr] = None,
6139    from_: t.Optional[ExpOrStr] = None,
6140    dialect: DialectType = None,
6141    **opts,
6142) -> Update:
6143    """
6144    Creates an update statement.
6145
6146    Example:
6147        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6148        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6149
6150    Args:
6151        *properties: dictionary of properties to set which are
6152            auto converted to sql objects eg None -> NULL
6153        where: sql conditional parsed into a WHERE statement
6154        from_: sql statement parsed into a FROM statement
6155        dialect: the dialect used to parse the input expressions.
6156        **opts: other options to use to parse the input expressions.
6157
6158    Returns:
6159        Update: the syntax tree for the UPDATE statement.
6160    """
6161    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6162    update_expr.set(
6163        "expressions",
6164        [
6165            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6166            for k, v in properties.items()
6167        ],
6168    )
6169    if from_:
6170        update_expr.set(
6171            "from",
6172            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6173        )
6174    if isinstance(where, Condition):
6175        where = Where(this=where)
6176    if where:
6177        update_expr.set(
6178            "where",
6179            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6180        )
6181    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:
6184def delete(
6185    table: ExpOrStr,
6186    where: t.Optional[ExpOrStr] = None,
6187    returning: t.Optional[ExpOrStr] = None,
6188    dialect: DialectType = None,
6189    **opts,
6190) -> Delete:
6191    """
6192    Builds a delete statement.
6193
6194    Example:
6195        >>> delete("my_table", where="id > 1").sql()
6196        'DELETE FROM my_table WHERE id > 1'
6197
6198    Args:
6199        where: sql conditional parsed into a WHERE statement
6200        returning: sql conditional parsed into a RETURNING statement
6201        dialect: the dialect used to parse the input expressions.
6202        **opts: other options to use to parse the input expressions.
6203
6204    Returns:
6205        Delete: the syntax tree for the DELETE statement.
6206    """
6207    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6208    if where:
6209        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6210    if returning:
6211        delete_expr = t.cast(
6212            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6213        )
6214    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:
6217def insert(
6218    expression: ExpOrStr,
6219    into: ExpOrStr,
6220    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6221    overwrite: t.Optional[bool] = None,
6222    returning: t.Optional[ExpOrStr] = None,
6223    dialect: DialectType = None,
6224    copy: bool = True,
6225    **opts,
6226) -> Insert:
6227    """
6228    Builds an INSERT statement.
6229
6230    Example:
6231        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6232        'INSERT INTO tbl VALUES (1, 2, 3)'
6233
6234    Args:
6235        expression: the sql string or expression of the INSERT statement
6236        into: the tbl to insert data to.
6237        columns: optionally the table's column names.
6238        overwrite: whether to INSERT OVERWRITE or not.
6239        returning: sql conditional parsed into a RETURNING statement
6240        dialect: the dialect used to parse the input expressions.
6241        copy: whether to copy the expression.
6242        **opts: other options to use to parse the input expressions.
6243
6244    Returns:
6245        Insert: the syntax tree for the INSERT statement.
6246    """
6247    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6248    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6249
6250    if columns:
6251        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6252
6253    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6254
6255    if returning:
6256        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6257
6258    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:
6261def condition(
6262    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6263) -> Condition:
6264    """
6265    Initialize a logical condition expression.
6266
6267    Example:
6268        >>> condition("x=1").sql()
6269        'x = 1'
6270
6271        This is helpful for composing larger logical syntax trees:
6272        >>> where = condition("x=1")
6273        >>> where = where.and_("y=1")
6274        >>> Select().from_("tbl").select("*").where(where).sql()
6275        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6276
6277    Args:
6278        *expression: the SQL code string to parse.
6279            If an Expression instance is passed, this is used as-is.
6280        dialect: the dialect used to parse the input expression (in the case that the
6281            input expression is a SQL string).
6282        copy: Whether to copy `expression` (only applies to expressions).
6283        **opts: other options to use to parse the input expressions (again, in the case
6284            that the input expression is a SQL string).
6285
6286    Returns:
6287        The new Condition instance
6288    """
6289    return maybe_parse(
6290        expression,
6291        into=Condition,
6292        dialect=dialect,
6293        copy=copy,
6294        **opts,
6295    )

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

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

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

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

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

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

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

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

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

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

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:
7248def true() -> Boolean:
7249    """
7250    Returns a true Boolean expression.
7251    """
7252    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7255def false() -> Boolean:
7256    """
7257    Returns a false Boolean expression.
7258    """
7259    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7262def null() -> Null:
7263    """
7264    Returns a Null expression.
7265    """
7266    return Null()

Returns a Null expression.