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

Retrieves the argument with key "this".

expression: Any
138    @property
139    def expression(self) -> t.Any:
140        """
141        Retrieves the argument with key "expression".
142        """
143        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
145    @property
146    def expressions(self) -> t.List[t.Any]:
147        """
148        Retrieves the argument with key "expressions".
149        """
150        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
152    def text(self, key) -> str:
153        """
154        Returns a textual representation of the argument corresponding to "key". This can only be used
155        for args that are strings or leaf Expression instances, such as identifiers and literals.
156        """
157        field = self.args.get(key)
158        if isinstance(field, str):
159            return field
160        if isinstance(field, (Identifier, Literal, Var)):
161            return field.this
162        if isinstance(field, (Star, Null)):
163            return field.name
164        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
166    @property
167    def is_string(self) -> bool:
168        """
169        Checks whether a Literal expression is a string.
170        """
171        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
173    @property
174    def is_number(self) -> bool:
175        """
176        Checks whether a Literal expression is a number.
177        """
178        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_negative: bool
180    @property
181    def is_negative(self) -> bool:
182        """
183        Checks whether an expression is negative.
184
185        Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.
186        """
187        return isinstance(self, Neg) or (self.is_number and self.this.startswith("-"))

Checks whether an expression is negative.

Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.

is_int: bool
189    @property
190    def is_int(self) -> bool:
191        """
192        Checks whether a Literal expression is an integer.
193        """
194        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
196    @property
197    def is_star(self) -> bool:
198        """Checks whether an expression is a star."""
199        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
201    @property
202    def alias(self) -> str:
203        """
204        Returns the alias of the expression, or an empty string if it's not aliased.
205        """
206        if isinstance(self.args.get("alias"), TableAlias):
207            return self.args["alias"].name
208        return self.text("alias")

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        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]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
306        if self.comments is None:
307            self.comments = []
308        if comments:
309            for comment in comments:
310                _, *meta = comment.split(SQLGLOT_META)
311                if meta:
312                    for kv in "".join(meta).split(","):
313                        k, *v = kv.split("=")
314                        value = v[0].strip() if v else True
315                        self.meta[k.strip()] = value
316                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
318    def append(self, arg_key: str, value: t.Any) -> None:
319        """
320        Appends value to arg_key if it's a list or sets it as a new list.
321
322        Args:
323            arg_key (str): name of the list expression arg
324            value (Any): value to append to the list
325        """
326        if type(self.args.get(arg_key)) is not list:
327            self.args[arg_key] = []
328        self._set_parent(arg_key, value)
329        values = self.args[arg_key]
330        if hasattr(value, "parent"):
331            value.index = len(values)
332        values.append(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, index: Optional[int] = None) -> None:
334    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
335        """
336        Sets arg_key to value.
337
338        Args:
339            arg_key: name of the expression arg.
340            value: value to set the arg to.
341            index: if the arg is a list, this specifies what position to add the value in it.
342        """
343        if index is not None:
344            expressions = self.args.get(arg_key) or []
345
346            if seq_get(expressions, index) is None:
347                return
348            if value is None:
349                expressions.pop(index)
350                for v in expressions[index:]:
351                    v.index = v.index - 1
352                return
353
354            if isinstance(value, list):
355                expressions.pop(index)
356                expressions[index:index] = value
357            else:
358                expressions[index] = value
359
360            value = expressions
361        elif value is None:
362            self.args.pop(arg_key, None)
363            return
364
365        self.args[arg_key] = value
366        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
depth: int
380    @property
381    def depth(self) -> int:
382        """
383        Returns the depth of this tree.
384        """
385        if self.parent:
386            return self.parent.depth + 1
387        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
389    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
390        """Yields the key and expression for all arguments, exploding list args."""
391        # remove tuple when python 3.7 is deprecated
392        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
393            if type(vs) is list:
394                for v in reversed(vs) if reverse else vs:
395                    if hasattr(v, "parent"):
396                        yield v
397            else:
398                if hasattr(vs, "parent"):
399                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
401    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
402        """
403        Returns the first node in this tree which matches at least one of
404        the specified types.
405
406        Args:
407            expression_types: the expression type(s) to match.
408            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
409
410        Returns:
411            The node which matches the criteria or None if no such node was found.
412        """
413        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]:
415    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
416        """
417        Returns a generator object which visits all nodes in this tree and only
418        yields those that match at least one of the specified expression types.
419
420        Args:
421            expression_types: the expression type(s) to match.
422            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
423
424        Returns:
425            The generator object.
426        """
427        for expression in self.walk(bfs=bfs):
428            if isinstance(expression, expression_types):
429                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]:
431    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
432        """
433        Returns a nearest parent matching expression_types.
434
435        Args:
436            expression_types: the expression type(s) to match.
437
438        Returns:
439            The parent node.
440        """
441        ancestor = self.parent
442        while ancestor and not isinstance(ancestor, expression_types):
443            ancestor = ancestor.parent
444        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]
446    @property
447    def parent_select(self) -> t.Optional[Select]:
448        """
449        Returns the parent select statement.
450        """
451        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
453    @property
454    def same_parent(self) -> bool:
455        """Returns if the parent is the same class as itself."""
456        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
458    def root(self) -> Expression:
459        """
460        Returns the root expression of this tree.
461        """
462        expression = self
463        while expression.parent:
464            expression = expression.parent
465        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
467    def walk(
468        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
469    ) -> t.Iterator[Expression]:
470        """
471        Returns a generator object which visits all nodes in this tree.
472
473        Args:
474            bfs: if set to True the BFS traversal order will be applied,
475                otherwise the DFS traversal will be used instead.
476            prune: callable that returns True if the generator should stop traversing
477                this branch of the tree.
478
479        Returns:
480            the generator object.
481        """
482        if bfs:
483            yield from self.bfs(prune=prune)
484        else:
485            yield from self.dfs(prune=prune)

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

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

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
487    def dfs(
488        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
489    ) -> t.Iterator[Expression]:
490        """
491        Returns a generator object which visits all nodes in this tree in
492        the DFS (Depth-first) order.
493
494        Returns:
495            The generator object.
496        """
497        stack = [self]
498
499        while stack:
500            node = stack.pop()
501
502            yield node
503
504            if prune and prune(node):
505                continue
506
507            for v in node.iter_expressions(reverse=True):
508                stack.append(v)

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: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
510    def bfs(
511        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
512    ) -> t.Iterator[Expression]:
513        """
514        Returns a generator object which visits all nodes in this tree in
515        the BFS (Breadth-first) order.
516
517        Returns:
518            The generator object.
519        """
520        queue = deque([self])
521
522        while queue:
523            node = queue.popleft()
524
525            yield node
526
527            if prune and prune(node):
528                continue
529
530            for v in node.iter_expressions():
531                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
533    def unnest(self):
534        """
535        Returns the first non parenthesis child or self.
536        """
537        expression = self
538        while type(expression) is Paren:
539            expression = expression.this
540        return expression

Returns the first non parenthesis child or self.

def unalias(self):
542    def unalias(self):
543        """
544        Returns the inner expression if this is an Alias.
545        """
546        if isinstance(self, Alias):
547            return self.this
548        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
550    def unnest_operands(self):
551        """
552        Returns unnested operands as a tuple.
553        """
554        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
556    def flatten(self, unnest=True):
557        """
558        Returns a generator which yields child nodes whose parents are the same class.
559
560        A AND B AND C -> [A, B, C]
561        """
562        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
563            if type(node) is not self.__class__:
564                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:
572    def to_s(self) -> str:
573        """
574        Same as __repr__, but includes additional information which can be useful
575        for debugging, like empty or missing args and the AST nodes' object IDs.
576        """
577        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:
579    def sql(self, dialect: DialectType = None, **opts) -> str:
580        """
581        Returns SQL string representation of this tree.
582
583        Args:
584            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
585            opts: other `sqlglot.generator.Generator` options.
586
587        Returns:
588            The SQL string.
589        """
590        from sqlglot.dialects import Dialect
591
592        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: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
594    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
595        """
596        Visits all tree nodes (excluding already transformed ones)
597        and applies the given transformation function to each node.
598
599        Args:
600            fun: a function which takes a node as an argument and returns a
601                new transformed node or the same node without modifications. If the function
602                returns None, then the corresponding node will be removed from the syntax tree.
603            copy: if set to True a new tree instance is constructed, otherwise the tree is
604                modified in place.
605
606        Returns:
607            The transformed tree.
608        """
609        root = None
610        new_node = None
611
612        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
613            parent, arg_key, index = node.parent, node.arg_key, node.index
614            new_node = fun(node, *args, **kwargs)
615
616            if not root:
617                root = new_node
618            elif new_node is not node:
619                parent.set(arg_key, new_node, index)
620
621        assert root
622        return root.assert_is(Expression)

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

Arguments:
  • fun: 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: 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):
630    def replace(self, expression):
631        """
632        Swap out this expression with a new expression.
633
634        For example::
635
636            >>> tree = Select().select("x").from_("tbl")
637            >>> tree.find(Column).replace(column("y"))
638            Column(
639              this=Identifier(this=y, quoted=False))
640            >>> tree.sql()
641            'SELECT y FROM tbl'
642
643        Args:
644            expression: new node
645
646        Returns:
647            The new expression or expressions.
648        """
649        parent = self.parent
650
651        if not parent or parent is expression:
652            return expression
653
654        key = self.arg_key
655        value = parent.args.get(key)
656
657        if type(expression) is list and isinstance(value, Expression):
658            # We are trying to replace an Expression with a list, so it's assumed that
659            # the intention was to really replace the parent of this expression.
660            value.parent.replace(expression)
661        else:
662            parent.set(key, expression, self.index)
663
664        if expression is not self:
665            self.parent = None
666            self.arg_key = None
667            self.index = None
668
669        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:
671    def pop(self: E) -> E:
672        """
673        Remove this expression from its AST.
674
675        Returns:
676            The popped expression.
677        """
678        self.replace(None)
679        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
681    def assert_is(self, type_: t.Type[E]) -> E:
682        """
683        Assert that this `Expression` is an instance of `type_`.
684
685        If it is NOT an instance of `type_`, this raises an assertion error.
686        Otherwise, this returns this expression.
687
688        Examples:
689            This is useful for type security in chained expressions:
690
691            >>> import sqlglot
692            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
693            'SELECT x, z FROM y'
694        """
695        if not isinstance(self, type_):
696            raise AssertionError(f"{self} is not {type_}.")
697        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]:
699    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
700        """
701        Checks if this expression is valid (e.g. all mandatory args are set).
702
703        Args:
704            args: a sequence of values that were used to instantiate a Func expression. This is used
705                to check that the provided arguments don't exceed the function argument limit.
706
707        Returns:
708            A list of error messages for all possible errors that were found.
709        """
710        errors: t.List[str] = []
711
712        for k in self.args:
713            if k not in self.arg_types:
714                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
715        for k, mandatory in self.arg_types.items():
716            v = self.args.get(k)
717            if mandatory and (v is None or (isinstance(v, list) and not v)):
718                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
719
720        if (
721            args
722            and isinstance(self, Func)
723            and len(args) > len(self.arg_types)
724            and not self.is_var_len_args
725        ):
726            errors.append(
727                f"The number of provided arguments ({len(args)}) is greater than "
728                f"the maximum number of supported arguments ({len(self.arg_types)})"
729            )
730
731        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):
733    def dump(self):
734        """
735        Dump this Expression to a JSON-serializable dict.
736        """
737        from sqlglot.serde import dump
738
739        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
741    @classmethod
742    def load(cls, obj):
743        """
744        Load a dict (as returned by `Expression.dump`) into an Expression instance.
745        """
746        from sqlglot.serde import load
747
748        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:
750    def and_(
751        self,
752        *expressions: t.Optional[ExpOrStr],
753        dialect: DialectType = None,
754        copy: bool = True,
755        **opts,
756    ) -> Condition:
757        """
758        AND this condition with one or multiple expressions.
759
760        Example:
761            >>> condition("x=1").and_("y=1").sql()
762            'x = 1 AND y = 1'
763
764        Args:
765            *expressions: the SQL code strings to parse.
766                If an `Expression` instance is passed, it will be used as-is.
767            dialect: the dialect used to parse the input expression.
768            copy: whether to copy the involved expressions (only applies to Expressions).
769            opts: other options to use to parse the input expressions.
770
771        Returns:
772            The new And condition.
773        """
774        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:
776    def or_(
777        self,
778        *expressions: t.Optional[ExpOrStr],
779        dialect: DialectType = None,
780        copy: bool = True,
781        **opts,
782    ) -> Condition:
783        """
784        OR this condition with one or multiple expressions.
785
786        Example:
787            >>> condition("x=1").or_("y=1").sql()
788            'x = 1 OR y = 1'
789
790        Args:
791            *expressions: the SQL code strings to parse.
792                If an `Expression` instance is passed, it will be used as-is.
793            dialect: the dialect used to parse the input expression.
794            copy: whether to copy the involved expressions (only applies to Expressions).
795            opts: other options to use to parse the input expressions.
796
797        Returns:
798            The new Or condition.
799        """
800        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):
802    def not_(self, copy: bool = True):
803        """
804        Wrap this condition with NOT.
805
806        Example:
807            >>> condition("x=1").not_().sql()
808            'NOT x = 1'
809
810        Args:
811            copy: whether to copy this object.
812
813        Returns:
814            The new Not instance.
815        """
816        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:
818    def as_(
819        self,
820        alias: str | Identifier,
821        quoted: t.Optional[bool] = None,
822        dialect: DialectType = None,
823        copy: bool = True,
824        **opts,
825    ) -> Alias:
826        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:
851    def isin(
852        self,
853        *expressions: t.Any,
854        query: t.Optional[ExpOrStr] = None,
855        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
856        copy: bool = True,
857        **opts,
858    ) -> In:
859        subquery = maybe_parse(query, copy=copy, **opts) if query else None
860        if subquery and not isinstance(subquery, Subquery):
861            subquery = subquery.subquery(copy=False)
862
863        return In(
864            this=maybe_copy(self, copy),
865            expressions=[convert(e, copy=copy) for e in expressions],
866            query=subquery,
867            unnest=(
868                Unnest(
869                    expressions=[
870                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
871                        for e in ensure_list(unnest)
872                    ]
873                )
874                if unnest
875                else None
876            ),
877        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
879    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
880        return Between(
881            this=maybe_copy(self, copy),
882            low=convert(low, copy=copy, **opts),
883            high=convert(high, copy=copy, **opts),
884        )
def is_( self, other: Union[str, Expression]) -> Is:
886    def is_(self, other: ExpOrStr) -> Is:
887        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
889    def like(self, other: ExpOrStr) -> Like:
890        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
892    def ilike(self, other: ExpOrStr) -> ILike:
893        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
895    def eq(self, other: t.Any) -> EQ:
896        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
898    def neq(self, other: t.Any) -> NEQ:
899        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
901    def rlike(self, other: ExpOrStr) -> RegexpLike:
902        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
904    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
905        div = self._binop(Div, other)
906        div.args["typed"] = typed
907        div.args["safe"] = safe
908        return div
def asc(self, nulls_first: bool = True) -> Ordered:
910    def asc(self, nulls_first: bool = True) -> Ordered:
911        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
913    def desc(self, nulls_first: bool = False) -> Ordered:
914        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):
997class Condition(Expression):
998    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1005class DerivedTable(Expression):
1006    @property
1007    def selects(self) -> t.List[Expression]:
1008        return self.this.selects if isinstance(self.this, Query) else []
1009
1010    @property
1011    def named_selects(self) -> t.List[str]:
1012        return [select.output_name for select in self.selects]
selects: List[Expression]
1006    @property
1007    def selects(self) -> t.List[Expression]:
1008        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1010    @property
1011    def named_selects(self) -> t.List[str]:
1012        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1015class Query(Expression):
1016    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1017        """
1018        Returns a `Subquery` that wraps around this query.
1019
1020        Example:
1021            >>> subquery = Select().select("x").from_("tbl").subquery()
1022            >>> Select().select("x").from_(subquery).sql()
1023            'SELECT x FROM (SELECT x FROM tbl)'
1024
1025        Args:
1026            alias: an optional alias for the subquery.
1027            copy: if `False`, modify this expression instance in-place.
1028        """
1029        instance = maybe_copy(self, copy)
1030        if not isinstance(alias, Expression):
1031            alias = TableAlias(this=to_identifier(alias)) if alias else None
1032
1033        return Subquery(this=instance, alias=alias)
1034
1035    def limit(
1036        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1037    ) -> Q:
1038        """
1039        Adds a LIMIT clause to this query.
1040
1041        Example:
1042            >>> select("1").union(select("1")).limit(1).sql()
1043            'SELECT 1 UNION SELECT 1 LIMIT 1'
1044
1045        Args:
1046            expression: the SQL code string to parse.
1047                This can also be an integer.
1048                If a `Limit` instance is passed, it will be used as-is.
1049                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1050            dialect: the dialect used to parse the input expression.
1051            copy: if `False`, modify this expression instance in-place.
1052            opts: other options to use to parse the input expressions.
1053
1054        Returns:
1055            A limited Select expression.
1056        """
1057        return _apply_builder(
1058            expression=expression,
1059            instance=self,
1060            arg="limit",
1061            into=Limit,
1062            prefix="LIMIT",
1063            dialect=dialect,
1064            copy=copy,
1065            into_arg="expression",
1066            **opts,
1067        )
1068
1069    def offset(
1070        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1071    ) -> Q:
1072        """
1073        Set the OFFSET expression.
1074
1075        Example:
1076            >>> Select().from_("tbl").select("x").offset(10).sql()
1077            'SELECT x FROM tbl OFFSET 10'
1078
1079        Args:
1080            expression: the SQL code string to parse.
1081                This can also be an integer.
1082                If a `Offset` instance is passed, this is used as-is.
1083                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1084            dialect: the dialect used to parse the input expression.
1085            copy: if `False`, modify this expression instance in-place.
1086            opts: other options to use to parse the input expressions.
1087
1088        Returns:
1089            The modified Select expression.
1090        """
1091        return _apply_builder(
1092            expression=expression,
1093            instance=self,
1094            arg="offset",
1095            into=Offset,
1096            prefix="OFFSET",
1097            dialect=dialect,
1098            copy=copy,
1099            into_arg="expression",
1100            **opts,
1101        )
1102
1103    def order_by(
1104        self: Q,
1105        *expressions: t.Optional[ExpOrStr],
1106        append: bool = True,
1107        dialect: DialectType = None,
1108        copy: bool = True,
1109        **opts,
1110    ) -> Q:
1111        """
1112        Set the ORDER BY expression.
1113
1114        Example:
1115            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1116            'SELECT x FROM tbl ORDER BY x DESC'
1117
1118        Args:
1119            *expressions: the SQL code strings to parse.
1120                If a `Group` instance is passed, this is used as-is.
1121                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1122            append: if `True`, add to any existing expressions.
1123                Otherwise, this flattens all the `Order` expression into a single expression.
1124            dialect: the dialect used to parse the input expression.
1125            copy: if `False`, modify this expression instance in-place.
1126            opts: other options to use to parse the input expressions.
1127
1128        Returns:
1129            The modified Select expression.
1130        """
1131        return _apply_child_list_builder(
1132            *expressions,
1133            instance=self,
1134            arg="order",
1135            append=append,
1136            copy=copy,
1137            prefix="ORDER BY",
1138            into=Order,
1139            dialect=dialect,
1140            **opts,
1141        )
1142
1143    @property
1144    def ctes(self) -> t.List[CTE]:
1145        """Returns a list of all the CTEs attached to this query."""
1146        with_ = self.args.get("with")
1147        return with_.expressions if with_ else []
1148
1149    @property
1150    def selects(self) -> t.List[Expression]:
1151        """Returns the query's projections."""
1152        raise NotImplementedError("Query objects must implement `selects`")
1153
1154    @property
1155    def named_selects(self) -> t.List[str]:
1156        """Returns the output names of the query's projections."""
1157        raise NotImplementedError("Query objects must implement `named_selects`")
1158
1159    def select(
1160        self: Q,
1161        *expressions: t.Optional[ExpOrStr],
1162        append: bool = True,
1163        dialect: DialectType = None,
1164        copy: bool = True,
1165        **opts,
1166    ) -> Q:
1167        """
1168        Append to or set the SELECT expressions.
1169
1170        Example:
1171            >>> Select().select("x", "y").sql()
1172            'SELECT x, y'
1173
1174        Args:
1175            *expressions: the SQL code strings to parse.
1176                If an `Expression` instance is passed, it will be used as-is.
1177            append: if `True`, add to any existing expressions.
1178                Otherwise, this resets the expressions.
1179            dialect: the dialect used to parse the input expressions.
1180            copy: if `False`, modify this expression instance in-place.
1181            opts: other options to use to parse the input expressions.
1182
1183        Returns:
1184            The modified Query expression.
1185        """
1186        raise NotImplementedError("Query objects must implement `select`")
1187
1188    def with_(
1189        self: Q,
1190        alias: ExpOrStr,
1191        as_: ExpOrStr,
1192        recursive: t.Optional[bool] = None,
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the common table expressions.
1200
1201        Example:
1202            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1203            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1204
1205        Args:
1206            alias: the SQL code string to parse as the table name.
1207                If an `Expression` instance is passed, this is used as-is.
1208            as_: the SQL code string to parse as the table expression.
1209                If an `Expression` instance is passed, it will be used as-is.
1210            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1211            append: if `True`, add to any existing expressions.
1212                Otherwise, this resets the expressions.
1213            dialect: the dialect used to parse the input expression.
1214            copy: if `False`, modify this expression instance in-place.
1215            opts: other options to use to parse the input expressions.
1216
1217        Returns:
1218            The modified expression.
1219        """
1220        return _apply_cte_builder(
1221            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1222        )
1223
1224    def union(
1225        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1226    ) -> Union:
1227        """
1228        Builds a UNION expression.
1229
1230        Example:
1231            >>> import sqlglot
1232            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1233            'SELECT * FROM foo UNION SELECT * FROM bla'
1234
1235        Args:
1236            expression: the SQL code string.
1237                If an `Expression` instance is passed, it will be used as-is.
1238            distinct: set the DISTINCT flag if and only if this is true.
1239            dialect: the dialect used to parse the input expression.
1240            opts: other options to use to parse the input expressions.
1241
1242        Returns:
1243            The new Union expression.
1244        """
1245        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1246
1247    def intersect(
1248        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1249    ) -> Intersect:
1250        """
1251        Builds an INTERSECT expression.
1252
1253        Example:
1254            >>> import sqlglot
1255            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1256            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1257
1258        Args:
1259            expression: the SQL code string.
1260                If an `Expression` instance is passed, it will be used as-is.
1261            distinct: set the DISTINCT flag if and only if this is true.
1262            dialect: the dialect used to parse the input expression.
1263            opts: other options to use to parse the input expressions.
1264
1265        Returns:
1266            The new Intersect expression.
1267        """
1268        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1269
1270    def except_(
1271        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1272    ) -> Except:
1273        """
1274        Builds an EXCEPT expression.
1275
1276        Example:
1277            >>> import sqlglot
1278            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1279            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1280
1281        Args:
1282            expression: the SQL code string.
1283                If an `Expression` instance is passed, it will be used as-is.
1284            distinct: set the DISTINCT flag if and only if this is true.
1285            dialect: the dialect used to parse the input expression.
1286            opts: other options to use to parse the input expressions.
1287
1288        Returns:
1289            The new Except expression.
1290        """
1291        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1016    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1017        """
1018        Returns a `Subquery` that wraps around this query.
1019
1020        Example:
1021            >>> subquery = Select().select("x").from_("tbl").subquery()
1022            >>> Select().select("x").from_(subquery).sql()
1023            'SELECT x FROM (SELECT x FROM tbl)'
1024
1025        Args:
1026            alias: an optional alias for the subquery.
1027            copy: if `False`, modify this expression instance in-place.
1028        """
1029        instance = maybe_copy(self, copy)
1030        if not isinstance(alias, Expression):
1031            alias = TableAlias(this=to_identifier(alias)) if alias else None
1032
1033        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: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1035    def limit(
1036        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1037    ) -> Q:
1038        """
1039        Adds a LIMIT clause to this query.
1040
1041        Example:
1042            >>> select("1").union(select("1")).limit(1).sql()
1043            'SELECT 1 UNION SELECT 1 LIMIT 1'
1044
1045        Args:
1046            expression: the SQL code string to parse.
1047                This can also be an integer.
1048                If a `Limit` instance is passed, it will be used as-is.
1049                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1050            dialect: the dialect used to parse the input expression.
1051            copy: if `False`, modify this expression instance in-place.
1052            opts: other options to use to parse the input expressions.
1053
1054        Returns:
1055            A limited Select expression.
1056        """
1057        return _apply_builder(
1058            expression=expression,
1059            instance=self,
1060            arg="limit",
1061            into=Limit,
1062            prefix="LIMIT",
1063            dialect=dialect,
1064            copy=copy,
1065            into_arg="expression",
1066            **opts,
1067        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 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: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1069    def offset(
1070        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1071    ) -> Q:
1072        """
1073        Set the OFFSET expression.
1074
1075        Example:
1076            >>> Select().from_("tbl").select("x").offset(10).sql()
1077            'SELECT x FROM tbl OFFSET 10'
1078
1079        Args:
1080            expression: the SQL code string to parse.
1081                This can also be an integer.
1082                If a `Offset` instance is passed, this is used as-is.
1083                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1084            dialect: the dialect used to parse the input expression.
1085            copy: if `False`, modify this expression instance in-place.
1086            opts: other options to use to parse the input expressions.
1087
1088        Returns:
1089            The modified Select expression.
1090        """
1091        return _apply_builder(
1092            expression=expression,
1093            instance=self,
1094            arg="offset",
1095            into=Offset,
1096            prefix="OFFSET",
1097            dialect=dialect,
1098            copy=copy,
1099            into_arg="expression",
1100            **opts,
1101        )

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 order_by( self: ~Q, *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) -> ~Q:
1103    def order_by(
1104        self: Q,
1105        *expressions: t.Optional[ExpOrStr],
1106        append: bool = True,
1107        dialect: DialectType = None,
1108        copy: bool = True,
1109        **opts,
1110    ) -> Q:
1111        """
1112        Set the ORDER BY expression.
1113
1114        Example:
1115            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1116            'SELECT x FROM tbl ORDER BY x DESC'
1117
1118        Args:
1119            *expressions: the SQL code strings to parse.
1120                If a `Group` instance is passed, this is used as-is.
1121                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1122            append: if `True`, add to any existing expressions.
1123                Otherwise, this flattens all the `Order` expression into a single expression.
1124            dialect: the dialect used to parse the input expression.
1125            copy: if `False`, modify this expression instance in-place.
1126            opts: other options to use to parse the input expressions.
1127
1128        Returns:
1129            The modified Select expression.
1130        """
1131        return _apply_child_list_builder(
1132            *expressions,
1133            instance=self,
1134            arg="order",
1135            append=append,
1136            copy=copy,
1137            prefix="ORDER BY",
1138            into=Order,
1139            dialect=dialect,
1140            **opts,
1141        )

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.

ctes: List[CTE]
1143    @property
1144    def ctes(self) -> t.List[CTE]:
1145        """Returns a list of all the CTEs attached to this query."""
1146        with_ = self.args.get("with")
1147        return with_.expressions if with_ else []

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

selects: List[Expression]
1149    @property
1150    def selects(self) -> t.List[Expression]:
1151        """Returns the query's projections."""
1152        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1154    @property
1155    def named_selects(self) -> t.List[str]:
1156        """Returns the output names of the query's projections."""
1157        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *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) -> ~Q:
1159    def select(
1160        self: Q,
1161        *expressions: t.Optional[ExpOrStr],
1162        append: bool = True,
1163        dialect: DialectType = None,
1164        copy: bool = True,
1165        **opts,
1166    ) -> Q:
1167        """
1168        Append to or set the SELECT expressions.
1169
1170        Example:
1171            >>> Select().select("x", "y").sql()
1172            'SELECT x, y'
1173
1174        Args:
1175            *expressions: the SQL code strings to parse.
1176                If an `Expression` instance is passed, it will be used as-is.
1177            append: if `True`, add to any existing expressions.
1178                Otherwise, this resets the expressions.
1179            dialect: the dialect used to parse the input expressions.
1180            copy: if `False`, modify this expression instance in-place.
1181            opts: other options to use to parse the input expressions.
1182
1183        Returns:
1184            The modified Query expression.
1185        """
1186        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: ~Q, 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) -> ~Q:
1188    def with_(
1189        self: Q,
1190        alias: ExpOrStr,
1191        as_: ExpOrStr,
1192        recursive: t.Optional[bool] = None,
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the common table expressions.
1200
1201        Example:
1202            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1203            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1204
1205        Args:
1206            alias: the SQL code string to parse as the table name.
1207                If an `Expression` instance is passed, this is used as-is.
1208            as_: the SQL code string to parse as the table expression.
1209                If an `Expression` instance is passed, it will be used as-is.
1210            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1211            append: if `True`, add to any existing expressions.
1212                Otherwise, this resets the expressions.
1213            dialect: the dialect used to parse the input expression.
1214            copy: if `False`, modify this expression instance in-place.
1215            opts: other options to use to parse the input expressions.
1216
1217        Returns:
1218            The modified expression.
1219        """
1220        return _apply_cte_builder(
1221            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1222        )

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:
1224    def union(
1225        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1226    ) -> Union:
1227        """
1228        Builds a UNION expression.
1229
1230        Example:
1231            >>> import sqlglot
1232            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1233            'SELECT * FROM foo UNION SELECT * FROM bla'
1234
1235        Args:
1236            expression: the SQL code string.
1237                If an `Expression` instance is passed, it will be used as-is.
1238            distinct: set the DISTINCT flag if and only if this is true.
1239            dialect: the dialect used to parse the input expression.
1240            opts: other options to use to parse the input expressions.
1241
1242        Returns:
1243            The new Union expression.
1244        """
1245        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:
1247    def intersect(
1248        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1249    ) -> Intersect:
1250        """
1251        Builds an INTERSECT expression.
1252
1253        Example:
1254            >>> import sqlglot
1255            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1256            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1257
1258        Args:
1259            expression: the SQL code string.
1260                If an `Expression` instance is passed, it will be used as-is.
1261            distinct: set the DISTINCT flag if and only if this is true.
1262            dialect: the dialect used to parse the input expression.
1263            opts: other options to use to parse the input expressions.
1264
1265        Returns:
1266            The new Intersect expression.
1267        """
1268        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:
1270    def except_(
1271        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1272    ) -> Except:
1273        """
1274        Builds an EXCEPT expression.
1275
1276        Example:
1277            >>> import sqlglot
1278            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1279            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1280
1281        Args:
1282            expression: the SQL code string.
1283                If an `Expression` instance is passed, it will be used as-is.
1284            distinct: set the DISTINCT flag if and only if this is true.
1285            dialect: the dialect used to parse the input expression.
1286            opts: other options to use to parse the input expressions.
1287
1288        Returns:
1289            The new Except expression.
1290        """
1291        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):
1294class UDTF(DerivedTable):
1295    @property
1296    def selects(self) -> t.List[Expression]:
1297        alias = self.args.get("alias")
1298        return alias.columns if alias else []
selects: List[Expression]
1295    @property
1296    def selects(self) -> t.List[Expression]:
1297        alias = self.args.get("alias")
1298        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1301class Cache(Expression):
1302    arg_types = {
1303        "this": True,
1304        "lazy": False,
1305        "options": False,
1306        "expression": False,
1307    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1310class Uncache(Expression):
1311    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1314class Refresh(Expression):
1315    pass
key = 'refresh'
class DDL(Expression):
1318class DDL(Expression):
1319    @property
1320    def ctes(self) -> t.List[CTE]:
1321        """Returns a list of all the CTEs attached to this statement."""
1322        with_ = self.args.get("with")
1323        return with_.expressions if with_ else []
1324
1325    @property
1326    def selects(self) -> t.List[Expression]:
1327        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1328        return self.expression.selects if isinstance(self.expression, Query) else []
1329
1330    @property
1331    def named_selects(self) -> t.List[str]:
1332        """
1333        If this statement contains a query (e.g. a CTAS), this returns the output
1334        names of the query's projections.
1335        """
1336        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1319    @property
1320    def ctes(self) -> t.List[CTE]:
1321        """Returns a list of all the CTEs attached to this statement."""
1322        with_ = self.args.get("with")
1323        return with_.expressions if with_ else []

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

selects: List[Expression]
1325    @property
1326    def selects(self) -> t.List[Expression]:
1327        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1328        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]
1330    @property
1331    def named_selects(self) -> t.List[str]:
1332        """
1333        If this statement contains a query (e.g. a CTAS), this returns the output
1334        names of the query's projections.
1335        """
1336        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):
1339class DML(Expression):
1340    def returning(
1341        self,
1342        expression: ExpOrStr,
1343        dialect: DialectType = None,
1344        copy: bool = True,
1345        **opts,
1346    ) -> DML:
1347        """
1348        Set the RETURNING expression. Not supported by all dialects.
1349
1350        Example:
1351            >>> delete("tbl").returning("*", dialect="postgres").sql()
1352            'DELETE FROM tbl RETURNING *'
1353
1354        Args:
1355            expression: the SQL code strings to parse.
1356                If an `Expression` instance is passed, it will be used as-is.
1357            dialect: the dialect used to parse the input expressions.
1358            copy: if `False`, modify this expression instance in-place.
1359            opts: other options to use to parse the input expressions.
1360
1361        Returns:
1362            Delete: the modified expression.
1363        """
1364        return _apply_builder(
1365            expression=expression,
1366            instance=self,
1367            arg="returning",
1368            prefix="RETURNING",
1369            dialect=dialect,
1370            copy=copy,
1371            into=Returning,
1372            **opts,
1373        )
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:
1340    def returning(
1341        self,
1342        expression: ExpOrStr,
1343        dialect: DialectType = None,
1344        copy: bool = True,
1345        **opts,
1346    ) -> DML:
1347        """
1348        Set the RETURNING expression. Not supported by all dialects.
1349
1350        Example:
1351            >>> delete("tbl").returning("*", dialect="postgres").sql()
1352            'DELETE FROM tbl RETURNING *'
1353
1354        Args:
1355            expression: the SQL code strings to parse.
1356                If an `Expression` instance is passed, it will be used as-is.
1357            dialect: the dialect used to parse the input expressions.
1358            copy: if `False`, modify this expression instance in-place.
1359            opts: other options to use to parse the input expressions.
1360
1361        Returns:
1362            Delete: the modified expression.
1363        """
1364        return _apply_builder(
1365            expression=expression,
1366            instance=self,
1367            arg="returning",
1368            prefix="RETURNING",
1369            dialect=dialect,
1370            copy=copy,
1371            into=Returning,
1372            **opts,
1373        )

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):
1376class Create(DDL):
1377    arg_types = {
1378        "with": False,
1379        "this": True,
1380        "kind": True,
1381        "expression": False,
1382        "exists": False,
1383        "properties": False,
1384        "replace": False,
1385        "unique": False,
1386        "indexes": False,
1387        "no_schema_binding": False,
1388        "begin": False,
1389        "end": False,
1390        "clone": False,
1391    }
1392
1393    @property
1394    def kind(self) -> t.Optional[str]:
1395        kind = self.args.get("kind")
1396        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]
1393    @property
1394    def kind(self) -> t.Optional[str]:
1395        kind = self.args.get("kind")
1396        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1399class SequenceProperties(Expression):
1400    arg_types = {
1401        "increment": False,
1402        "minvalue": False,
1403        "maxvalue": False,
1404        "cache": False,
1405        "start": False,
1406        "owned": False,
1407        "options": False,
1408    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1411class TruncateTable(Expression):
1412    arg_types = {
1413        "expressions": True,
1414        "is_database": False,
1415        "exists": False,
1416        "only": False,
1417        "cluster": False,
1418        "identity": False,
1419        "option": False,
1420        "partition": False,
1421    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1427class Clone(Expression):
1428    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1431class Describe(Expression):
1432    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1435class Kill(Expression):
1436    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1439class Pragma(Expression):
1440    pass
key = 'pragma'
class Set(Expression):
1443class Set(Expression):
1444    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1447class Heredoc(Expression):
1448    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1451class SetItem(Expression):
1452    arg_types = {
1453        "this": False,
1454        "expressions": False,
1455        "kind": False,
1456        "collate": False,  # MySQL SET NAMES statement
1457        "global": False,
1458    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1461class Show(Expression):
1462    arg_types = {
1463        "this": True,
1464        "history": False,
1465        "terse": False,
1466        "target": False,
1467        "offset": False,
1468        "starts_with": False,
1469        "limit": False,
1470        "from": False,
1471        "like": False,
1472        "where": False,
1473        "db": False,
1474        "scope": False,
1475        "scope_kind": False,
1476        "full": False,
1477        "mutex": False,
1478        "query": False,
1479        "channel": False,
1480        "global": False,
1481        "log": False,
1482        "position": False,
1483        "types": False,
1484    }
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):
1487class UserDefinedFunction(Expression):
1488    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1491class CharacterSet(Expression):
1492    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1495class With(Expression):
1496    arg_types = {"expressions": True, "recursive": False}
1497
1498    @property
1499    def recursive(self) -> bool:
1500        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1498    @property
1499    def recursive(self) -> bool:
1500        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1503class WithinGroup(Expression):
1504    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1509class CTE(DerivedTable):
1510    arg_types = {
1511        "this": True,
1512        "alias": True,
1513        "scalar": False,
1514        "materialized": False,
1515    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class TableAlias(Expression):
1518class TableAlias(Expression):
1519    arg_types = {"this": False, "columns": False}
1520
1521    @property
1522    def columns(self):
1523        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1521    @property
1522    def columns(self):
1523        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1526class BitString(Condition):
1527    pass
key = 'bitstring'
class HexString(Condition):
1530class HexString(Condition):
1531    pass
key = 'hexstring'
class ByteString(Condition):
1534class ByteString(Condition):
1535    pass
key = 'bytestring'
class RawString(Condition):
1538class RawString(Condition):
1539    pass
key = 'rawstring'
class UnicodeString(Condition):
1542class UnicodeString(Condition):
1543    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1546class Column(Condition):
1547    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1548
1549    @property
1550    def table(self) -> str:
1551        return self.text("table")
1552
1553    @property
1554    def db(self) -> str:
1555        return self.text("db")
1556
1557    @property
1558    def catalog(self) -> str:
1559        return self.text("catalog")
1560
1561    @property
1562    def output_name(self) -> str:
1563        return self.name
1564
1565    @property
1566    def parts(self) -> t.List[Identifier]:
1567        """Return the parts of a column in order catalog, db, table, name."""
1568        return [
1569            t.cast(Identifier, self.args[part])
1570            for part in ("catalog", "db", "table", "this")
1571            if self.args.get(part)
1572        ]
1573
1574    def to_dot(self) -> Dot | Identifier:
1575        """Converts the column into a dot expression."""
1576        parts = self.parts
1577        parent = self.parent
1578
1579        while parent:
1580            if isinstance(parent, Dot):
1581                parts.append(parent.expression)
1582            parent = parent.parent
1583
1584        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
1549    @property
1550    def table(self) -> str:
1551        return self.text("table")
db: str
1553    @property
1554    def db(self) -> str:
1555        return self.text("db")
catalog: str
1557    @property
1558    def catalog(self) -> str:
1559        return self.text("catalog")
output_name: str
1561    @property
1562    def output_name(self) -> str:
1563        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]
1565    @property
1566    def parts(self) -> t.List[Identifier]:
1567        """Return the parts of a column in order catalog, db, table, name."""
1568        return [
1569            t.cast(Identifier, self.args[part])
1570            for part in ("catalog", "db", "table", "this")
1571            if self.args.get(part)
1572        ]

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

def to_dot(self) -> Dot | Identifier:
1574    def to_dot(self) -> Dot | Identifier:
1575        """Converts the column into a dot expression."""
1576        parts = self.parts
1577        parent = self.parent
1578
1579        while parent:
1580            if isinstance(parent, Dot):
1581                parts.append(parent.expression)
1582            parent = parent.parent
1583
1584        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1587class ColumnPosition(Expression):
1588    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1591class ColumnDef(Expression):
1592    arg_types = {
1593        "this": True,
1594        "kind": False,
1595        "constraints": False,
1596        "exists": False,
1597        "position": False,
1598    }
1599
1600    @property
1601    def constraints(self) -> t.List[ColumnConstraint]:
1602        return self.args.get("constraints") or []
1603
1604    @property
1605    def kind(self) -> t.Optional[DataType]:
1606        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1600    @property
1601    def constraints(self) -> t.List[ColumnConstraint]:
1602        return self.args.get("constraints") or []
kind: Optional[DataType]
1604    @property
1605    def kind(self) -> t.Optional[DataType]:
1606        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1609class AlterColumn(Expression):
1610    arg_types = {
1611        "this": True,
1612        "dtype": False,
1613        "collate": False,
1614        "using": False,
1615        "default": False,
1616        "drop": False,
1617        "comment": False,
1618    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1621class RenameColumn(Expression):
1622    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1625class RenameTable(Expression):
1626    pass
key = 'renametable'
class SwapTable(Expression):
1629class SwapTable(Expression):
1630    pass
key = 'swaptable'
class Comment(Expression):
1633class Comment(Expression):
1634    arg_types = {
1635        "this": True,
1636        "kind": True,
1637        "expression": True,
1638        "exists": False,
1639        "materialized": False,
1640    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1643class Comprehension(Expression):
1644    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):
1648class MergeTreeTTLAction(Expression):
1649    arg_types = {
1650        "this": True,
1651        "delete": False,
1652        "recompress": False,
1653        "to_disk": False,
1654        "to_volume": False,
1655    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1659class MergeTreeTTL(Expression):
1660    arg_types = {
1661        "expressions": True,
1662        "where": False,
1663        "group": False,
1664        "aggregates": False,
1665    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1669class IndexConstraintOption(Expression):
1670    arg_types = {
1671        "key_block_size": False,
1672        "using": False,
1673        "parser": False,
1674        "comment": False,
1675        "visible": False,
1676        "engine_attr": False,
1677        "secondary_engine_attr": False,
1678    }
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):
1681class ColumnConstraint(Expression):
1682    arg_types = {"this": False, "kind": True}
1683
1684    @property
1685    def kind(self) -> ColumnConstraintKind:
1686        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1684    @property
1685    def kind(self) -> ColumnConstraintKind:
1686        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1689class ColumnConstraintKind(Expression):
1690    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1693class AutoIncrementColumnConstraint(ColumnConstraintKind):
1694    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1697class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1698    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1701class CaseSpecificColumnConstraint(ColumnConstraintKind):
1702    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1705class CharacterSetColumnConstraint(ColumnConstraintKind):
1706    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1709class CheckColumnConstraint(ColumnConstraintKind):
1710    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1713class ClusteredColumnConstraint(ColumnConstraintKind):
1714    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1717class CollateColumnConstraint(ColumnConstraintKind):
1718    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1721class CommentColumnConstraint(ColumnConstraintKind):
1722    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1725class CompressColumnConstraint(ColumnConstraintKind):
1726    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1729class DateFormatColumnConstraint(ColumnConstraintKind):
1730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1733class DefaultColumnConstraint(ColumnConstraintKind):
1734    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1737class EncodeColumnConstraint(ColumnConstraintKind):
1738    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1742class ExcludeColumnConstraint(ColumnConstraintKind):
1743    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1746class EphemeralColumnConstraint(ColumnConstraintKind):
1747    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1750class WithOperator(Expression):
1751    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1754class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1755    # this: True -> ALWAYS, this: False -> BY DEFAULT
1756    arg_types = {
1757        "this": False,
1758        "expression": False,
1759        "on_null": False,
1760        "start": False,
1761        "increment": False,
1762        "minvalue": False,
1763        "maxvalue": False,
1764        "cycle": False,
1765    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1768class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1769    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1774class IndexColumnConstraint(ColumnConstraintKind):
1775    arg_types = {
1776        "this": False,
1777        "expressions": False,
1778        "kind": False,
1779        "index_type": False,
1780        "options": False,
1781        "expression": False,  # Clickhouse
1782        "granularity": False,
1783    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1786class InlineLengthColumnConstraint(ColumnConstraintKind):
1787    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1790class NonClusteredColumnConstraint(ColumnConstraintKind):
1791    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1794class NotForReplicationColumnConstraint(ColumnConstraintKind):
1795    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1798class NotNullColumnConstraint(ColumnConstraintKind):
1799    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1803class OnUpdateColumnConstraint(ColumnConstraintKind):
1804    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1808class TransformColumnConstraint(ColumnConstraintKind):
1809    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1812class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1813    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1816class TitleColumnConstraint(ColumnConstraintKind):
1817    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1820class UniqueColumnConstraint(ColumnConstraintKind):
1821    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):
1824class UppercaseColumnConstraint(ColumnConstraintKind):
1825    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1828class PathColumnConstraint(ColumnConstraintKind):
1829    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1834class ComputedColumnConstraint(ColumnConstraintKind):
1835    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1838class Constraint(Expression):
1839    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1842class Delete(DML):
1843    arg_types = {
1844        "with": False,
1845        "this": False,
1846        "using": False,
1847        "where": False,
1848        "returning": False,
1849        "limit": False,
1850        "tables": False,  # Multiple-Table Syntax (MySQL)
1851    }
1852
1853    def delete(
1854        self,
1855        table: ExpOrStr,
1856        dialect: DialectType = None,
1857        copy: bool = True,
1858        **opts,
1859    ) -> Delete:
1860        """
1861        Create a DELETE expression or replace the table on an existing DELETE expression.
1862
1863        Example:
1864            >>> delete("tbl").sql()
1865            'DELETE FROM tbl'
1866
1867        Args:
1868            table: the table from which to delete.
1869            dialect: the dialect used to parse the input expression.
1870            copy: if `False`, modify this expression instance in-place.
1871            opts: other options to use to parse the input expressions.
1872
1873        Returns:
1874            Delete: the modified expression.
1875        """
1876        return _apply_builder(
1877            expression=table,
1878            instance=self,
1879            arg="this",
1880            dialect=dialect,
1881            into=Table,
1882            copy=copy,
1883            **opts,
1884        )
1885
1886    def where(
1887        self,
1888        *expressions: t.Optional[ExpOrStr],
1889        append: bool = True,
1890        dialect: DialectType = None,
1891        copy: bool = True,
1892        **opts,
1893    ) -> Delete:
1894        """
1895        Append to or set the WHERE expressions.
1896
1897        Example:
1898            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1899            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1900
1901        Args:
1902            *expressions: the SQL code strings to parse.
1903                If an `Expression` instance is passed, it will be used as-is.
1904                Multiple expressions are combined with an AND operator.
1905            append: if `True`, AND the new expressions to any existing expression.
1906                Otherwise, this resets the expression.
1907            dialect: the dialect used to parse the input expressions.
1908            copy: if `False`, modify this expression instance in-place.
1909            opts: other options to use to parse the input expressions.
1910
1911        Returns:
1912            Delete: the modified expression.
1913        """
1914        return _apply_conjunction_builder(
1915            *expressions,
1916            instance=self,
1917            arg="where",
1918            append=append,
1919            into=Where,
1920            dialect=dialect,
1921            copy=copy,
1922            **opts,
1923        )
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:
1853    def delete(
1854        self,
1855        table: ExpOrStr,
1856        dialect: DialectType = None,
1857        copy: bool = True,
1858        **opts,
1859    ) -> Delete:
1860        """
1861        Create a DELETE expression or replace the table on an existing DELETE expression.
1862
1863        Example:
1864            >>> delete("tbl").sql()
1865            'DELETE FROM tbl'
1866
1867        Args:
1868            table: the table from which to delete.
1869            dialect: the dialect used to parse the input expression.
1870            copy: if `False`, modify this expression instance in-place.
1871            opts: other options to use to parse the input expressions.
1872
1873        Returns:
1874            Delete: the modified expression.
1875        """
1876        return _apply_builder(
1877            expression=table,
1878            instance=self,
1879            arg="this",
1880            dialect=dialect,
1881            into=Table,
1882            copy=copy,
1883            **opts,
1884        )

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:
1886    def where(
1887        self,
1888        *expressions: t.Optional[ExpOrStr],
1889        append: bool = True,
1890        dialect: DialectType = None,
1891        copy: bool = True,
1892        **opts,
1893    ) -> Delete:
1894        """
1895        Append to or set the WHERE expressions.
1896
1897        Example:
1898            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1899            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1900
1901        Args:
1902            *expressions: the SQL code strings to parse.
1903                If an `Expression` instance is passed, it will be used as-is.
1904                Multiple expressions are combined with an AND operator.
1905            append: if `True`, AND the new expressions to any existing expression.
1906                Otherwise, this resets the expression.
1907            dialect: the dialect used to parse the input expressions.
1908            copy: if `False`, modify this expression instance in-place.
1909            opts: other options to use to parse the input expressions.
1910
1911        Returns:
1912            Delete: the modified expression.
1913        """
1914        return _apply_conjunction_builder(
1915            *expressions,
1916            instance=self,
1917            arg="where",
1918            append=append,
1919            into=Where,
1920            dialect=dialect,
1921            copy=copy,
1922            **opts,
1923        )

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):
1926class Drop(Expression):
1927    arg_types = {
1928        "this": False,
1929        "kind": False,
1930        "expressions": False,
1931        "exists": False,
1932        "temporary": False,
1933        "materialized": False,
1934        "cascade": False,
1935        "constraints": False,
1936        "purge": False,
1937    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1940class Filter(Expression):
1941    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1944class Check(Expression):
1945    pass
key = 'check'
class Connect(Expression):
1949class Connect(Expression):
1950    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class Prior(Expression):
1953class Prior(Expression):
1954    pass
key = 'prior'
class Directory(Expression):
1957class Directory(Expression):
1958    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1959    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1962class ForeignKey(Expression):
1963    arg_types = {
1964        "expressions": True,
1965        "reference": False,
1966        "delete": False,
1967        "update": False,
1968    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1971class ColumnPrefix(Expression):
1972    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1975class PrimaryKey(Expression):
1976    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1981class Into(Expression):
1982    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1985class From(Expression):
1986    @property
1987    def name(self) -> str:
1988        return self.this.name
1989
1990    @property
1991    def alias_or_name(self) -> str:
1992        return self.this.alias_or_name
name: str
1986    @property
1987    def name(self) -> str:
1988        return self.this.name
alias_or_name: str
1990    @property
1991    def alias_or_name(self) -> str:
1992        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1995class Having(Expression):
1996    pass
key = 'having'
class Hint(Expression):
1999class Hint(Expression):
2000    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2003class JoinHint(Expression):
2004    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2007class Identifier(Expression):
2008    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2009
2010    @property
2011    def quoted(self) -> bool:
2012        return bool(self.args.get("quoted"))
2013
2014    @property
2015    def hashable_args(self) -> t.Any:
2016        return (self.this, self.quoted)
2017
2018    @property
2019    def output_name(self) -> str:
2020        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2010    @property
2011    def quoted(self) -> bool:
2012        return bool(self.args.get("quoted"))
hashable_args: Any
2014    @property
2015    def hashable_args(self) -> t.Any:
2016        return (self.this, self.quoted)
output_name: str
2018    @property
2019    def output_name(self) -> str:
2020        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):
2024class Opclass(Expression):
2025    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2028class Index(Expression):
2029    arg_types = {
2030        "this": False,
2031        "table": False,
2032        "unique": False,
2033        "primary": False,
2034        "amp": False,  # teradata
2035        "params": False,
2036    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2039class IndexParameters(Expression):
2040    arg_types = {
2041        "using": False,
2042        "include": False,
2043        "columns": False,
2044        "with_storage": False,
2045        "partition_by": False,
2046        "tablespace": False,
2047        "where": False,
2048    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
2051class Insert(DDL, DML):
2052    arg_types = {
2053        "hint": False,
2054        "with": False,
2055        "is_function": False,
2056        "this": True,
2057        "expression": False,
2058        "conflict": False,
2059        "returning": False,
2060        "overwrite": False,
2061        "exists": False,
2062        "alternative": False,
2063        "where": False,
2064        "ignore": False,
2065        "by_name": False,
2066        "stored": False,
2067    }
2068
2069    def with_(
2070        self,
2071        alias: ExpOrStr,
2072        as_: ExpOrStr,
2073        recursive: t.Optional[bool] = None,
2074        append: bool = True,
2075        dialect: DialectType = None,
2076        copy: bool = True,
2077        **opts,
2078    ) -> Insert:
2079        """
2080        Append to or set the common table expressions.
2081
2082        Example:
2083            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2084            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2085
2086        Args:
2087            alias: the SQL code string to parse as the table name.
2088                If an `Expression` instance is passed, this is used as-is.
2089            as_: the SQL code string to parse as the table expression.
2090                If an `Expression` instance is passed, it will be used as-is.
2091            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2092            append: if `True`, add to any existing expressions.
2093                Otherwise, this resets the expressions.
2094            dialect: the dialect used to parse the input expression.
2095            copy: if `False`, modify this expression instance in-place.
2096            opts: other options to use to parse the input expressions.
2097
2098        Returns:
2099            The modified expression.
2100        """
2101        return _apply_cte_builder(
2102            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2103        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': 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:
2069    def with_(
2070        self,
2071        alias: ExpOrStr,
2072        as_: ExpOrStr,
2073        recursive: t.Optional[bool] = None,
2074        append: bool = True,
2075        dialect: DialectType = None,
2076        copy: bool = True,
2077        **opts,
2078    ) -> Insert:
2079        """
2080        Append to or set the common table expressions.
2081
2082        Example:
2083            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2084            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2085
2086        Args:
2087            alias: the SQL code string to parse as the table name.
2088                If an `Expression` instance is passed, this is used as-is.
2089            as_: the SQL code string to parse as the table expression.
2090                If an `Expression` instance is passed, it will be used as-is.
2091            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2092            append: if `True`, add to any existing expressions.
2093                Otherwise, this resets the expressions.
2094            dialect: the dialect used to parse the input expression.
2095            copy: if `False`, modify this expression instance in-place.
2096            opts: other options to use to parse the input expressions.
2097
2098        Returns:
2099            The modified expression.
2100        """
2101        return _apply_cte_builder(
2102            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2103        )

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):
2106class OnConflict(Expression):
2107    arg_types = {
2108        "duplicate": False,
2109        "expressions": False,
2110        "action": False,
2111        "conflict_keys": False,
2112        "constraint": False,
2113    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2116class Returning(Expression):
2117    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2121class Introducer(Expression):
2122    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2126class National(Expression):
2127    pass
key = 'national'
class LoadData(Expression):
2130class LoadData(Expression):
2131    arg_types = {
2132        "this": True,
2133        "local": False,
2134        "overwrite": False,
2135        "inpath": True,
2136        "partition": False,
2137        "input_format": False,
2138        "serde": False,
2139    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2142class Partition(Expression):
2143    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2146class PartitionRange(Expression):
2147    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2150class Fetch(Expression):
2151    arg_types = {
2152        "direction": False,
2153        "count": False,
2154        "percent": False,
2155        "with_ties": False,
2156    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2159class Group(Expression):
2160    arg_types = {
2161        "expressions": False,
2162        "grouping_sets": False,
2163        "cube": False,
2164        "rollup": False,
2165        "totals": False,
2166        "all": False,
2167    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2170class Lambda(Expression):
2171    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2174class Limit(Expression):
2175    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):
2178class Literal(Condition):
2179    arg_types = {"this": True, "is_string": True}
2180
2181    @property
2182    def hashable_args(self) -> t.Any:
2183        return (self.this, self.args.get("is_string"))
2184
2185    @classmethod
2186    def number(cls, number) -> Literal:
2187        return cls(this=str(number), is_string=False)
2188
2189    @classmethod
2190    def string(cls, string) -> Literal:
2191        return cls(this=str(string), is_string=True)
2192
2193    @property
2194    def output_name(self) -> str:
2195        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2181    @property
2182    def hashable_args(self) -> t.Any:
2183        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2185    @classmethod
2186    def number(cls, number) -> Literal:
2187        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2189    @classmethod
2190    def string(cls, string) -> Literal:
2191        return cls(this=str(string), is_string=True)
output_name: str
2193    @property
2194    def output_name(self) -> str:
2195        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):
2198class Join(Expression):
2199    arg_types = {
2200        "this": True,
2201        "on": False,
2202        "side": False,
2203        "kind": False,
2204        "using": False,
2205        "method": False,
2206        "global": False,
2207        "hint": False,
2208        "match_condition": False,  # Snowflake
2209    }
2210
2211    @property
2212    def method(self) -> str:
2213        return self.text("method").upper()
2214
2215    @property
2216    def kind(self) -> str:
2217        return self.text("kind").upper()
2218
2219    @property
2220    def side(self) -> str:
2221        return self.text("side").upper()
2222
2223    @property
2224    def hint(self) -> str:
2225        return self.text("hint").upper()
2226
2227    @property
2228    def alias_or_name(self) -> str:
2229        return self.this.alias_or_name
2230
2231    def on(
2232        self,
2233        *expressions: t.Optional[ExpOrStr],
2234        append: bool = True,
2235        dialect: DialectType = None,
2236        copy: bool = True,
2237        **opts,
2238    ) -> Join:
2239        """
2240        Append to or set the ON expressions.
2241
2242        Example:
2243            >>> import sqlglot
2244            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2245            'JOIN x ON y = 1'
2246
2247        Args:
2248            *expressions: the SQL code strings to parse.
2249                If an `Expression` instance is passed, it will be used as-is.
2250                Multiple expressions are combined with an AND operator.
2251            append: if `True`, AND the new expressions to any existing expression.
2252                Otherwise, this resets the expression.
2253            dialect: the dialect used to parse the input expressions.
2254            copy: if `False`, modify this expression instance in-place.
2255            opts: other options to use to parse the input expressions.
2256
2257        Returns:
2258            The modified Join expression.
2259        """
2260        join = _apply_conjunction_builder(
2261            *expressions,
2262            instance=self,
2263            arg="on",
2264            append=append,
2265            dialect=dialect,
2266            copy=copy,
2267            **opts,
2268        )
2269
2270        if join.kind == "CROSS":
2271            join.set("kind", None)
2272
2273        return join
2274
2275    def using(
2276        self,
2277        *expressions: t.Optional[ExpOrStr],
2278        append: bool = True,
2279        dialect: DialectType = None,
2280        copy: bool = True,
2281        **opts,
2282    ) -> Join:
2283        """
2284        Append to or set the USING expressions.
2285
2286        Example:
2287            >>> import sqlglot
2288            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2289            'JOIN x USING (foo, bla)'
2290
2291        Args:
2292            *expressions: the SQL code strings to parse.
2293                If an `Expression` instance is passed, it will be used as-is.
2294            append: if `True`, concatenate the new expressions to the existing "using" list.
2295                Otherwise, this resets the expression.
2296            dialect: the dialect used to parse the input expressions.
2297            copy: if `False`, modify this expression instance in-place.
2298            opts: other options to use to parse the input expressions.
2299
2300        Returns:
2301            The modified Join expression.
2302        """
2303        join = _apply_list_builder(
2304            *expressions,
2305            instance=self,
2306            arg="using",
2307            append=append,
2308            dialect=dialect,
2309            copy=copy,
2310            **opts,
2311        )
2312
2313        if join.kind == "CROSS":
2314            join.set("kind", None)
2315
2316        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2211    @property
2212    def method(self) -> str:
2213        return self.text("method").upper()
kind: str
2215    @property
2216    def kind(self) -> str:
2217        return self.text("kind").upper()
side: str
2219    @property
2220    def side(self) -> str:
2221        return self.text("side").upper()
hint: str
2223    @property
2224    def hint(self) -> str:
2225        return self.text("hint").upper()
alias_or_name: str
2227    @property
2228    def alias_or_name(self) -> str:
2229        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:
2231    def on(
2232        self,
2233        *expressions: t.Optional[ExpOrStr],
2234        append: bool = True,
2235        dialect: DialectType = None,
2236        copy: bool = True,
2237        **opts,
2238    ) -> Join:
2239        """
2240        Append to or set the ON expressions.
2241
2242        Example:
2243            >>> import sqlglot
2244            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2245            'JOIN x ON y = 1'
2246
2247        Args:
2248            *expressions: the SQL code strings to parse.
2249                If an `Expression` instance is passed, it will be used as-is.
2250                Multiple expressions are combined with an AND operator.
2251            append: if `True`, AND the new expressions to any existing expression.
2252                Otherwise, this resets the expression.
2253            dialect: the dialect used to parse the input expressions.
2254            copy: if `False`, modify this expression instance in-place.
2255            opts: other options to use to parse the input expressions.
2256
2257        Returns:
2258            The modified Join expression.
2259        """
2260        join = _apply_conjunction_builder(
2261            *expressions,
2262            instance=self,
2263            arg="on",
2264            append=append,
2265            dialect=dialect,
2266            copy=copy,
2267            **opts,
2268        )
2269
2270        if join.kind == "CROSS":
2271            join.set("kind", None)
2272
2273        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:
2275    def using(
2276        self,
2277        *expressions: t.Optional[ExpOrStr],
2278        append: bool = True,
2279        dialect: DialectType = None,
2280        copy: bool = True,
2281        **opts,
2282    ) -> Join:
2283        """
2284        Append to or set the USING expressions.
2285
2286        Example:
2287            >>> import sqlglot
2288            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2289            'JOIN x USING (foo, bla)'
2290
2291        Args:
2292            *expressions: the SQL code strings to parse.
2293                If an `Expression` instance is passed, it will be used as-is.
2294            append: if `True`, concatenate the new expressions to the existing "using" list.
2295                Otherwise, this resets the expression.
2296            dialect: the dialect used to parse the input expressions.
2297            copy: if `False`, modify this expression instance in-place.
2298            opts: other options to use to parse the input expressions.
2299
2300        Returns:
2301            The modified Join expression.
2302        """
2303        join = _apply_list_builder(
2304            *expressions,
2305            instance=self,
2306            arg="using",
2307            append=append,
2308            dialect=dialect,
2309            copy=copy,
2310            **opts,
2311        )
2312
2313        if join.kind == "CROSS":
2314            join.set("kind", None)
2315
2316        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):
2319class Lateral(UDTF):
2320    arg_types = {
2321        "this": True,
2322        "view": False,
2323        "outer": False,
2324        "alias": False,
2325        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2326    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2329class MatchRecognizeMeasure(Expression):
2330    arg_types = {
2331        "this": True,
2332        "window_frame": False,
2333    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2336class MatchRecognize(Expression):
2337    arg_types = {
2338        "partition_by": False,
2339        "order": False,
2340        "measures": False,
2341        "rows": False,
2342        "after": False,
2343        "pattern": False,
2344        "define": False,
2345        "alias": False,
2346    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2351class Final(Expression):
2352    pass
key = 'final'
class Offset(Expression):
2355class Offset(Expression):
2356    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2359class Order(Expression):
2360    arg_types = {
2361        "this": False,
2362        "expressions": True,
2363        "interpolate": False,
2364        "siblings": False,
2365    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2369class WithFill(Expression):
2370    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2375class Cluster(Order):
2376    pass
key = 'cluster'
class Distribute(Order):
2379class Distribute(Order):
2380    pass
key = 'distribute'
class Sort(Order):
2383class Sort(Order):
2384    pass
key = 'sort'
class Ordered(Expression):
2387class Ordered(Expression):
2388    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):
2391class Property(Expression):
2392    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2395class AlgorithmProperty(Property):
2396    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2399class AutoIncrementProperty(Property):
2400    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2404class AutoRefreshProperty(Property):
2405    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2408class BackupProperty(Property):
2409    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2412class BlockCompressionProperty(Property):
2413    arg_types = {
2414        "autotemp": False,
2415        "always": False,
2416        "default": False,
2417        "manual": False,
2418        "never": False,
2419    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2422class CharacterSetProperty(Property):
2423    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2426class ChecksumProperty(Property):
2427    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2430class CollateProperty(Property):
2431    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2434class CopyGrantsProperty(Property):
2435    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2438class DataBlocksizeProperty(Property):
2439    arg_types = {
2440        "size": False,
2441        "units": False,
2442        "minimum": False,
2443        "maximum": False,
2444        "default": False,
2445    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2448class DefinerProperty(Property):
2449    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2452class DistKeyProperty(Property):
2453    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2456class DistStyleProperty(Property):
2457    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2460class EngineProperty(Property):
2461    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2464class HeapProperty(Property):
2465    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2468class ToTableProperty(Property):
2469    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2472class ExecuteAsProperty(Property):
2473    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2476class ExternalProperty(Property):
2477    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2480class FallbackProperty(Property):
2481    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2484class FileFormatProperty(Property):
2485    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2488class FreespaceProperty(Property):
2489    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2492class GlobalProperty(Property):
2493    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2496class IcebergProperty(Property):
2497    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2500class InheritsProperty(Property):
2501    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2504class InputModelProperty(Property):
2505    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2508class OutputModelProperty(Property):
2509    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2512class IsolatedLoadingProperty(Property):
2513    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2516class JournalProperty(Property):
2517    arg_types = {
2518        "no": False,
2519        "dual": False,
2520        "before": False,
2521        "local": False,
2522        "after": False,
2523    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2526class LanguageProperty(Property):
2527    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2531class ClusteredByProperty(Property):
2532    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2535class DictProperty(Property):
2536    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2539class DictSubProperty(Property):
2540    pass
key = 'dictsubproperty'
class DictRange(Property):
2543class DictRange(Property):
2544    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2549class OnCluster(Property):
2550    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2553class LikeProperty(Property):
2554    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2557class LocationProperty(Property):
2558    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2561class LockProperty(Property):
2562    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2565class LockingProperty(Property):
2566    arg_types = {
2567        "this": False,
2568        "kind": True,
2569        "for_or_in": False,
2570        "lock_type": True,
2571        "override": False,
2572    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2575class LogProperty(Property):
2576    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2579class MaterializedProperty(Property):
2580    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2583class MergeBlockRatioProperty(Property):
2584    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):
2587class NoPrimaryIndexProperty(Property):
2588    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2591class OnProperty(Property):
2592    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2595class OnCommitProperty(Property):
2596    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2599class PartitionedByProperty(Property):
2600    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2604class PartitionBoundSpec(Expression):
2605    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2606    arg_types = {
2607        "this": False,
2608        "expression": False,
2609        "from_expressions": False,
2610        "to_expressions": False,
2611    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2614class PartitionedOfProperty(Property):
2615    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2616    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2619class RemoteWithConnectionModelProperty(Property):
2620    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2623class ReturnsProperty(Property):
2624    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2627class RowFormatProperty(Property):
2628    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2631class RowFormatDelimitedProperty(Property):
2632    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2633    arg_types = {
2634        "fields": False,
2635        "escaped": False,
2636        "collection_items": False,
2637        "map_keys": False,
2638        "lines": False,
2639        "null": False,
2640        "serde": False,
2641    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2644class RowFormatSerdeProperty(Property):
2645    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2649class QueryTransform(Expression):
2650    arg_types = {
2651        "expressions": True,
2652        "command_script": True,
2653        "schema": False,
2654        "row_format_before": False,
2655        "record_writer": False,
2656        "row_format_after": False,
2657        "record_reader": False,
2658    }
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):
2661class SampleProperty(Property):
2662    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2665class SchemaCommentProperty(Property):
2666    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2669class SerdeProperties(Property):
2670    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2673class SetProperty(Property):
2674    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2677class SharingProperty(Property):
2678    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2681class SetConfigProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2685class SettingsProperty(Property):
2686    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2689class SortKeyProperty(Property):
2690    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2693class SqlReadWriteProperty(Property):
2694    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2697class SqlSecurityProperty(Property):
2698    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2701class StabilityProperty(Property):
2702    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2705class TemporaryProperty(Property):
2706    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2709class TransformModelProperty(Property):
2710    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2713class TransientProperty(Property):
2714    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2717class UnloggedProperty(Property):
2718    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2722class ViewAttributeProperty(Property):
2723    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2726class VolatileProperty(Property):
2727    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2730class WithDataProperty(Property):
2731    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2734class WithJournalTableProperty(Property):
2735    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2738class WithSystemVersioningProperty(Property):
2739    # this -> history table name, expression -> data consistency check
2740    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2743class Properties(Expression):
2744    arg_types = {"expressions": True}
2745
2746    NAME_TO_PROPERTY = {
2747        "ALGORITHM": AlgorithmProperty,
2748        "AUTO_INCREMENT": AutoIncrementProperty,
2749        "CHARACTER SET": CharacterSetProperty,
2750        "CLUSTERED_BY": ClusteredByProperty,
2751        "COLLATE": CollateProperty,
2752        "COMMENT": SchemaCommentProperty,
2753        "DEFINER": DefinerProperty,
2754        "DISTKEY": DistKeyProperty,
2755        "DISTSTYLE": DistStyleProperty,
2756        "ENGINE": EngineProperty,
2757        "EXECUTE AS": ExecuteAsProperty,
2758        "FORMAT": FileFormatProperty,
2759        "LANGUAGE": LanguageProperty,
2760        "LOCATION": LocationProperty,
2761        "LOCK": LockProperty,
2762        "PARTITIONED_BY": PartitionedByProperty,
2763        "RETURNS": ReturnsProperty,
2764        "ROW_FORMAT": RowFormatProperty,
2765        "SORTKEY": SortKeyProperty,
2766    }
2767
2768    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2769
2770    # CREATE property locations
2771    # Form: schema specified
2772    #   create [POST_CREATE]
2773    #     table a [POST_NAME]
2774    #     (b int) [POST_SCHEMA]
2775    #     with ([POST_WITH])
2776    #     index (b) [POST_INDEX]
2777    #
2778    # Form: alias selection
2779    #   create [POST_CREATE]
2780    #     table a [POST_NAME]
2781    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2782    #     index (c) [POST_INDEX]
2783    class Location(AutoName):
2784        POST_CREATE = auto()
2785        POST_NAME = auto()
2786        POST_SCHEMA = auto()
2787        POST_WITH = auto()
2788        POST_ALIAS = auto()
2789        POST_EXPRESSION = auto()
2790        POST_INDEX = auto()
2791        UNSUPPORTED = auto()
2792
2793    @classmethod
2794    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2795        expressions = []
2796        for key, value in properties_dict.items():
2797            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2798            if property_cls:
2799                expressions.append(property_cls(this=convert(value)))
2800            else:
2801                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2802
2803        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:
2793    @classmethod
2794    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2795        expressions = []
2796        for key, value in properties_dict.items():
2797            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2798            if property_cls:
2799                expressions.append(property_cls(this=convert(value)))
2800            else:
2801                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2802
2803        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2783    class Location(AutoName):
2784        POST_CREATE = auto()
2785        POST_NAME = auto()
2786        POST_SCHEMA = auto()
2787        POST_WITH = auto()
2788        POST_ALIAS = auto()
2789        POST_EXPRESSION = auto()
2790        POST_INDEX = auto()
2791        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):
2806class Qualify(Expression):
2807    pass
key = 'qualify'
class InputOutputFormat(Expression):
2810class InputOutputFormat(Expression):
2811    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2815class Return(Expression):
2816    pass
key = 'return'
class Reference(Expression):
2819class Reference(Expression):
2820    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2823class Tuple(Expression):
2824    arg_types = {"expressions": False}
2825
2826    def isin(
2827        self,
2828        *expressions: t.Any,
2829        query: t.Optional[ExpOrStr] = None,
2830        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2831        copy: bool = True,
2832        **opts,
2833    ) -> In:
2834        return In(
2835            this=maybe_copy(self, copy),
2836            expressions=[convert(e, copy=copy) for e in expressions],
2837            query=maybe_parse(query, copy=copy, **opts) if query else None,
2838            unnest=(
2839                Unnest(
2840                    expressions=[
2841                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2842                        for e in ensure_list(unnest)
2843                    ]
2844                )
2845                if unnest
2846                else None
2847            ),
2848        )
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:
2826    def isin(
2827        self,
2828        *expressions: t.Any,
2829        query: t.Optional[ExpOrStr] = None,
2830        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2831        copy: bool = True,
2832        **opts,
2833    ) -> In:
2834        return In(
2835            this=maybe_copy(self, copy),
2836            expressions=[convert(e, copy=copy) for e in expressions],
2837            query=maybe_parse(query, copy=copy, **opts) if query else None,
2838            unnest=(
2839                Unnest(
2840                    expressions=[
2841                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2842                        for e in ensure_list(unnest)
2843                    ]
2844                )
2845                if unnest
2846                else None
2847            ),
2848        )
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):
2879class QueryOption(Expression):
2880    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2884class WithTableHint(Expression):
2885    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2889class IndexTableHint(Expression):
2890    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2894class HistoricalData(Expression):
2895    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2898class Table(Expression):
2899    arg_types = {
2900        "this": False,
2901        "alias": False,
2902        "db": False,
2903        "catalog": False,
2904        "laterals": False,
2905        "joins": False,
2906        "pivots": False,
2907        "hints": False,
2908        "system_time": False,
2909        "version": False,
2910        "format": False,
2911        "pattern": False,
2912        "ordinality": False,
2913        "when": False,
2914        "only": False,
2915        "partition": False,
2916    }
2917
2918    @property
2919    def name(self) -> str:
2920        if isinstance(self.this, Func):
2921            return ""
2922        return self.this.name
2923
2924    @property
2925    def db(self) -> str:
2926        return self.text("db")
2927
2928    @property
2929    def catalog(self) -> str:
2930        return self.text("catalog")
2931
2932    @property
2933    def selects(self) -> t.List[Expression]:
2934        return []
2935
2936    @property
2937    def named_selects(self) -> t.List[str]:
2938        return []
2939
2940    @property
2941    def parts(self) -> t.List[Expression]:
2942        """Return the parts of a table in order catalog, db, table."""
2943        parts: t.List[Expression] = []
2944
2945        for arg in ("catalog", "db", "this"):
2946            part = self.args.get(arg)
2947
2948            if isinstance(part, Dot):
2949                parts.extend(part.flatten())
2950            elif isinstance(part, Expression):
2951                parts.append(part)
2952
2953        return parts
2954
2955    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2956        parts = self.parts
2957        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2958        alias = self.args.get("alias")
2959        if alias:
2960            col = alias_(col, alias.this, copy=copy)
2961        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, 'partition': False}
name: str
2918    @property
2919    def name(self) -> str:
2920        if isinstance(self.this, Func):
2921            return ""
2922        return self.this.name
db: str
2924    @property
2925    def db(self) -> str:
2926        return self.text("db")
catalog: str
2928    @property
2929    def catalog(self) -> str:
2930        return self.text("catalog")
selects: List[Expression]
2932    @property
2933    def selects(self) -> t.List[Expression]:
2934        return []
named_selects: List[str]
2936    @property
2937    def named_selects(self) -> t.List[str]:
2938        return []
parts: List[Expression]
2940    @property
2941    def parts(self) -> t.List[Expression]:
2942        """Return the parts of a table in order catalog, db, table."""
2943        parts: t.List[Expression] = []
2944
2945        for arg in ("catalog", "db", "this"):
2946            part = self.args.get(arg)
2947
2948            if isinstance(part, Dot):
2949                parts.extend(part.flatten())
2950            elif isinstance(part, Expression):
2951                parts.append(part)
2952
2953        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2955    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2956        parts = self.parts
2957        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2958        alias = self.args.get("alias")
2959        if alias:
2960            col = alias_(col, alias.this, copy=copy)
2961        return col
key = 'table'
class Union(Query):
2964class Union(Query):
2965    arg_types = {
2966        "with": False,
2967        "this": True,
2968        "expression": True,
2969        "distinct": False,
2970        "by_name": False,
2971        **QUERY_MODIFIERS,
2972    }
2973
2974    def select(
2975        self,
2976        *expressions: t.Optional[ExpOrStr],
2977        append: bool = True,
2978        dialect: DialectType = None,
2979        copy: bool = True,
2980        **opts,
2981    ) -> Union:
2982        this = maybe_copy(self, copy)
2983        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2984        this.expression.unnest().select(
2985            *expressions, append=append, dialect=dialect, copy=False, **opts
2986        )
2987        return this
2988
2989    @property
2990    def named_selects(self) -> t.List[str]:
2991        return self.this.unnest().named_selects
2992
2993    @property
2994    def is_star(self) -> bool:
2995        return self.this.is_star or self.expression.is_star
2996
2997    @property
2998    def selects(self) -> t.List[Expression]:
2999        return self.this.unnest().selects
3000
3001    @property
3002    def left(self) -> Expression:
3003        return self.this
3004
3005    @property
3006    def right(self) -> Expression:
3007        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:
2974    def select(
2975        self,
2976        *expressions: t.Optional[ExpOrStr],
2977        append: bool = True,
2978        dialect: DialectType = None,
2979        copy: bool = True,
2980        **opts,
2981    ) -> Union:
2982        this = maybe_copy(self, copy)
2983        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2984        this.expression.unnest().select(
2985            *expressions, append=append, dialect=dialect, copy=False, **opts
2986        )
2987        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]
2989    @property
2990    def named_selects(self) -> t.List[str]:
2991        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2993    @property
2994    def is_star(self) -> bool:
2995        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2997    @property
2998    def selects(self) -> t.List[Expression]:
2999        return self.this.unnest().selects

Returns the query's projections.

left: Expression
3001    @property
3002    def left(self) -> Expression:
3003        return self.this
right: Expression
3005    @property
3006    def right(self) -> Expression:
3007        return self.expression
key = 'union'
class Except(Union):
3010class Except(Union):
3011    pass
key = 'except'
class Intersect(Union):
3014class Intersect(Union):
3015    pass
key = 'intersect'
class Unnest(UDTF):
3018class Unnest(UDTF):
3019    arg_types = {
3020        "expressions": True,
3021        "alias": False,
3022        "offset": False,
3023    }
3024
3025    @property
3026    def selects(self) -> t.List[Expression]:
3027        columns = super().selects
3028        offset = self.args.get("offset")
3029        if offset:
3030            columns = columns + [to_identifier("offset") if offset is True else offset]
3031        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
3025    @property
3026    def selects(self) -> t.List[Expression]:
3027        columns = super().selects
3028        offset = self.args.get("offset")
3029        if offset:
3030            columns = columns + [to_identifier("offset") if offset is True else offset]
3031        return columns
key = 'unnest'
class Update(Expression):
3034class Update(Expression):
3035    arg_types = {
3036        "with": False,
3037        "this": False,
3038        "expressions": True,
3039        "from": False,
3040        "where": False,
3041        "returning": False,
3042        "order": False,
3043        "limit": False,
3044    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3047class Values(UDTF):
3048    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3051class Var(Expression):
3052    pass
key = 'var'
class Version(Expression):
3055class Version(Expression):
3056    """
3057    Time travel, iceberg, bigquery etc
3058    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3059    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3060    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3061    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3062    this is either TIMESTAMP or VERSION
3063    kind is ("AS OF", "BETWEEN")
3064    """
3065
3066    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3069class Schema(Expression):
3070    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3075class Lock(Expression):
3076    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3079class Select(Query):
3080    arg_types = {
3081        "with": False,
3082        "kind": False,
3083        "expressions": False,
3084        "hint": False,
3085        "distinct": False,
3086        "into": False,
3087        "from": False,
3088        **QUERY_MODIFIERS,
3089    }
3090
3091    def from_(
3092        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3093    ) -> Select:
3094        """
3095        Set the FROM expression.
3096
3097        Example:
3098            >>> Select().from_("tbl").select("x").sql()
3099            'SELECT x FROM tbl'
3100
3101        Args:
3102            expression : the SQL code strings to parse.
3103                If a `From` instance is passed, this is used as-is.
3104                If another `Expression` instance is passed, it will be wrapped in a `From`.
3105            dialect: the dialect used to parse the input expression.
3106            copy: if `False`, modify this expression instance in-place.
3107            opts: other options to use to parse the input expressions.
3108
3109        Returns:
3110            The modified Select expression.
3111        """
3112        return _apply_builder(
3113            expression=expression,
3114            instance=self,
3115            arg="from",
3116            into=From,
3117            prefix="FROM",
3118            dialect=dialect,
3119            copy=copy,
3120            **opts,
3121        )
3122
3123    def group_by(
3124        self,
3125        *expressions: t.Optional[ExpOrStr],
3126        append: bool = True,
3127        dialect: DialectType = None,
3128        copy: bool = True,
3129        **opts,
3130    ) -> Select:
3131        """
3132        Set the GROUP BY expression.
3133
3134        Example:
3135            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3136            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3137
3138        Args:
3139            *expressions: the SQL code strings to parse.
3140                If a `Group` instance is passed, this is used as-is.
3141                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3142                If nothing is passed in then a group by is not applied to the expression
3143            append: if `True`, add to any existing expressions.
3144                Otherwise, this flattens all the `Group` expression into a single expression.
3145            dialect: the dialect used to parse the input expression.
3146            copy: if `False`, modify this expression instance in-place.
3147            opts: other options to use to parse the input expressions.
3148
3149        Returns:
3150            The modified Select expression.
3151        """
3152        if not expressions:
3153            return self if not copy else self.copy()
3154
3155        return _apply_child_list_builder(
3156            *expressions,
3157            instance=self,
3158            arg="group",
3159            append=append,
3160            copy=copy,
3161            prefix="GROUP BY",
3162            into=Group,
3163            dialect=dialect,
3164            **opts,
3165        )
3166
3167    def sort_by(
3168        self,
3169        *expressions: t.Optional[ExpOrStr],
3170        append: bool = True,
3171        dialect: DialectType = None,
3172        copy: bool = True,
3173        **opts,
3174    ) -> Select:
3175        """
3176        Set the SORT BY expression.
3177
3178        Example:
3179            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3180            'SELECT x FROM tbl SORT BY x DESC'
3181
3182        Args:
3183            *expressions: the SQL code strings to parse.
3184                If a `Group` instance is passed, this is used as-is.
3185                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3186            append: if `True`, add to any existing expressions.
3187                Otherwise, this flattens all the `Order` expression into a single expression.
3188            dialect: the dialect used to parse the input expression.
3189            copy: if `False`, modify this expression instance in-place.
3190            opts: other options to use to parse the input expressions.
3191
3192        Returns:
3193            The modified Select expression.
3194        """
3195        return _apply_child_list_builder(
3196            *expressions,
3197            instance=self,
3198            arg="sort",
3199            append=append,
3200            copy=copy,
3201            prefix="SORT BY",
3202            into=Sort,
3203            dialect=dialect,
3204            **opts,
3205        )
3206
3207    def cluster_by(
3208        self,
3209        *expressions: t.Optional[ExpOrStr],
3210        append: bool = True,
3211        dialect: DialectType = None,
3212        copy: bool = True,
3213        **opts,
3214    ) -> Select:
3215        """
3216        Set the CLUSTER BY expression.
3217
3218        Example:
3219            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3220            'SELECT x FROM tbl CLUSTER BY x DESC'
3221
3222        Args:
3223            *expressions: the SQL code strings to parse.
3224                If a `Group` instance is passed, this is used as-is.
3225                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3226            append: if `True`, add to any existing expressions.
3227                Otherwise, this flattens all the `Order` expression into a single expression.
3228            dialect: the dialect used to parse the input expression.
3229            copy: if `False`, modify this expression instance in-place.
3230            opts: other options to use to parse the input expressions.
3231
3232        Returns:
3233            The modified Select expression.
3234        """
3235        return _apply_child_list_builder(
3236            *expressions,
3237            instance=self,
3238            arg="cluster",
3239            append=append,
3240            copy=copy,
3241            prefix="CLUSTER BY",
3242            into=Cluster,
3243            dialect=dialect,
3244            **opts,
3245        )
3246
3247    def select(
3248        self,
3249        *expressions: t.Optional[ExpOrStr],
3250        append: bool = True,
3251        dialect: DialectType = None,
3252        copy: bool = True,
3253        **opts,
3254    ) -> Select:
3255        return _apply_list_builder(
3256            *expressions,
3257            instance=self,
3258            arg="expressions",
3259            append=append,
3260            dialect=dialect,
3261            into=Expression,
3262            copy=copy,
3263            **opts,
3264        )
3265
3266    def lateral(
3267        self,
3268        *expressions: t.Optional[ExpOrStr],
3269        append: bool = True,
3270        dialect: DialectType = None,
3271        copy: bool = True,
3272        **opts,
3273    ) -> Select:
3274        """
3275        Append to or set the LATERAL expressions.
3276
3277        Example:
3278            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3279            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3280
3281        Args:
3282            *expressions: the SQL code strings to parse.
3283                If an `Expression` instance is passed, it will be used as-is.
3284            append: if `True`, add to any existing expressions.
3285                Otherwise, this resets the expressions.
3286            dialect: the dialect used to parse the input expressions.
3287            copy: if `False`, modify this expression instance in-place.
3288            opts: other options to use to parse the input expressions.
3289
3290        Returns:
3291            The modified Select expression.
3292        """
3293        return _apply_list_builder(
3294            *expressions,
3295            instance=self,
3296            arg="laterals",
3297            append=append,
3298            into=Lateral,
3299            prefix="LATERAL VIEW",
3300            dialect=dialect,
3301            copy=copy,
3302            **opts,
3303        )
3304
3305    def join(
3306        self,
3307        expression: ExpOrStr,
3308        on: t.Optional[ExpOrStr] = None,
3309        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3310        append: bool = True,
3311        join_type: t.Optional[str] = None,
3312        join_alias: t.Optional[Identifier | str] = None,
3313        dialect: DialectType = None,
3314        copy: bool = True,
3315        **opts,
3316    ) -> Select:
3317        """
3318        Append to or set the JOIN expressions.
3319
3320        Example:
3321            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3322            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3323
3324            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3325            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3326
3327            Use `join_type` to change the type of join:
3328
3329            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3330            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3331
3332        Args:
3333            expression: the SQL code string to parse.
3334                If an `Expression` instance is passed, it will be used as-is.
3335            on: optionally specify the join "on" criteria as a SQL string.
3336                If an `Expression` instance is passed, it will be used as-is.
3337            using: optionally specify the join "using" criteria as a SQL string.
3338                If an `Expression` instance is passed, it will be used as-is.
3339            append: if `True`, add to any existing expressions.
3340                Otherwise, this resets the expressions.
3341            join_type: if set, alter the parsed join type.
3342            join_alias: an optional alias for the joined source.
3343            dialect: the dialect used to parse the input expressions.
3344            copy: if `False`, modify this expression instance in-place.
3345            opts: other options to use to parse the input expressions.
3346
3347        Returns:
3348            Select: the modified expression.
3349        """
3350        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3351
3352        try:
3353            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3354        except ParseError:
3355            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3356
3357        join = expression if isinstance(expression, Join) else Join(this=expression)
3358
3359        if isinstance(join.this, Select):
3360            join.this.replace(join.this.subquery())
3361
3362        if join_type:
3363            method: t.Optional[Token]
3364            side: t.Optional[Token]
3365            kind: t.Optional[Token]
3366
3367            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3368
3369            if method:
3370                join.set("method", method.text)
3371            if side:
3372                join.set("side", side.text)
3373            if kind:
3374                join.set("kind", kind.text)
3375
3376        if on:
3377            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3378            join.set("on", on)
3379
3380        if using:
3381            join = _apply_list_builder(
3382                *ensure_list(using),
3383                instance=join,
3384                arg="using",
3385                append=append,
3386                copy=copy,
3387                into=Identifier,
3388                **opts,
3389            )
3390
3391        if join_alias:
3392            join.set("this", alias_(join.this, join_alias, table=True))
3393
3394        return _apply_list_builder(
3395            join,
3396            instance=self,
3397            arg="joins",
3398            append=append,
3399            copy=copy,
3400            **opts,
3401        )
3402
3403    def where(
3404        self,
3405        *expressions: t.Optional[ExpOrStr],
3406        append: bool = True,
3407        dialect: DialectType = None,
3408        copy: bool = True,
3409        **opts,
3410    ) -> Select:
3411        """
3412        Append to or set the WHERE expressions.
3413
3414        Example:
3415            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3416            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3417
3418        Args:
3419            *expressions: the SQL code strings to parse.
3420                If an `Expression` instance is passed, it will be used as-is.
3421                Multiple expressions are combined with an AND operator.
3422            append: if `True`, AND the new expressions to any existing expression.
3423                Otherwise, this resets the expression.
3424            dialect: the dialect used to parse the input expressions.
3425            copy: if `False`, modify this expression instance in-place.
3426            opts: other options to use to parse the input expressions.
3427
3428        Returns:
3429            Select: the modified expression.
3430        """
3431        return _apply_conjunction_builder(
3432            *expressions,
3433            instance=self,
3434            arg="where",
3435            append=append,
3436            into=Where,
3437            dialect=dialect,
3438            copy=copy,
3439            **opts,
3440        )
3441
3442    def having(
3443        self,
3444        *expressions: t.Optional[ExpOrStr],
3445        append: bool = True,
3446        dialect: DialectType = None,
3447        copy: bool = True,
3448        **opts,
3449    ) -> Select:
3450        """
3451        Append to or set the HAVING expressions.
3452
3453        Example:
3454            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3455            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3456
3457        Args:
3458            *expressions: the SQL code strings to parse.
3459                If an `Expression` instance is passed, it will be used as-is.
3460                Multiple expressions are combined with an AND operator.
3461            append: if `True`, AND the new expressions to any existing expression.
3462                Otherwise, this resets the expression.
3463            dialect: the dialect used to parse the input expressions.
3464            copy: if `False`, modify this expression instance in-place.
3465            opts: other options to use to parse the input expressions.
3466
3467        Returns:
3468            The modified Select expression.
3469        """
3470        return _apply_conjunction_builder(
3471            *expressions,
3472            instance=self,
3473            arg="having",
3474            append=append,
3475            into=Having,
3476            dialect=dialect,
3477            copy=copy,
3478            **opts,
3479        )
3480
3481    def window(
3482        self,
3483        *expressions: t.Optional[ExpOrStr],
3484        append: bool = True,
3485        dialect: DialectType = None,
3486        copy: bool = True,
3487        **opts,
3488    ) -> Select:
3489        return _apply_list_builder(
3490            *expressions,
3491            instance=self,
3492            arg="windows",
3493            append=append,
3494            into=Window,
3495            dialect=dialect,
3496            copy=copy,
3497            **opts,
3498        )
3499
3500    def qualify(
3501        self,
3502        *expressions: t.Optional[ExpOrStr],
3503        append: bool = True,
3504        dialect: DialectType = None,
3505        copy: bool = True,
3506        **opts,
3507    ) -> Select:
3508        return _apply_conjunction_builder(
3509            *expressions,
3510            instance=self,
3511            arg="qualify",
3512            append=append,
3513            into=Qualify,
3514            dialect=dialect,
3515            copy=copy,
3516            **opts,
3517        )
3518
3519    def distinct(
3520        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3521    ) -> Select:
3522        """
3523        Set the OFFSET expression.
3524
3525        Example:
3526            >>> Select().from_("tbl").select("x").distinct().sql()
3527            'SELECT DISTINCT x FROM tbl'
3528
3529        Args:
3530            ons: the expressions to distinct on
3531            distinct: whether the Select should be distinct
3532            copy: if `False`, modify this expression instance in-place.
3533
3534        Returns:
3535            Select: the modified expression.
3536        """
3537        instance = maybe_copy(self, copy)
3538        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3539        instance.set("distinct", Distinct(on=on) if distinct else None)
3540        return instance
3541
3542    def ctas(
3543        self,
3544        table: ExpOrStr,
3545        properties: t.Optional[t.Dict] = None,
3546        dialect: DialectType = None,
3547        copy: bool = True,
3548        **opts,
3549    ) -> Create:
3550        """
3551        Convert this expression to a CREATE TABLE AS statement.
3552
3553        Example:
3554            >>> Select().select("*").from_("tbl").ctas("x").sql()
3555            'CREATE TABLE x AS SELECT * FROM tbl'
3556
3557        Args:
3558            table: the SQL code string to parse as the table name.
3559                If another `Expression` instance is passed, it will be used as-is.
3560            properties: an optional mapping of table properties
3561            dialect: the dialect used to parse the input table.
3562            copy: if `False`, modify this expression instance in-place.
3563            opts: other options to use to parse the input table.
3564
3565        Returns:
3566            The new Create expression.
3567        """
3568        instance = maybe_copy(self, copy)
3569        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3570
3571        properties_expression = None
3572        if properties:
3573            properties_expression = Properties.from_dict(properties)
3574
3575        return Create(
3576            this=table_expression,
3577            kind="TABLE",
3578            expression=instance,
3579            properties=properties_expression,
3580        )
3581
3582    def lock(self, update: bool = True, copy: bool = True) -> Select:
3583        """
3584        Set the locking read mode for this expression.
3585
3586        Examples:
3587            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3588            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3589
3590            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3591            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3592
3593        Args:
3594            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3595            copy: if `False`, modify this expression instance in-place.
3596
3597        Returns:
3598            The modified expression.
3599        """
3600        inst = maybe_copy(self, copy)
3601        inst.set("locks", [Lock(update=update)])
3602
3603        return inst
3604
3605    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3606        """
3607        Set hints for this expression.
3608
3609        Examples:
3610            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3611            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3612
3613        Args:
3614            hints: The SQL code strings to parse as the hints.
3615                If an `Expression` instance is passed, it will be used as-is.
3616            dialect: The dialect used to parse the hints.
3617            copy: If `False`, modify this expression instance in-place.
3618
3619        Returns:
3620            The modified expression.
3621        """
3622        inst = maybe_copy(self, copy)
3623        inst.set(
3624            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3625        )
3626
3627        return inst
3628
3629    @property
3630    def named_selects(self) -> t.List[str]:
3631        return [e.output_name for e in self.expressions if e.alias_or_name]
3632
3633    @property
3634    def is_star(self) -> bool:
3635        return any(expression.is_star for expression in self.expressions)
3636
3637    @property
3638    def selects(self) -> t.List[Expression]:
3639        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:
3091    def from_(
3092        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3093    ) -> Select:
3094        """
3095        Set the FROM expression.
3096
3097        Example:
3098            >>> Select().from_("tbl").select("x").sql()
3099            'SELECT x FROM tbl'
3100
3101        Args:
3102            expression : the SQL code strings to parse.
3103                If a `From` instance is passed, this is used as-is.
3104                If another `Expression` instance is passed, it will be wrapped in a `From`.
3105            dialect: the dialect used to parse the input expression.
3106            copy: if `False`, modify this expression instance in-place.
3107            opts: other options to use to parse the input expressions.
3108
3109        Returns:
3110            The modified Select expression.
3111        """
3112        return _apply_builder(
3113            expression=expression,
3114            instance=self,
3115            arg="from",
3116            into=From,
3117            prefix="FROM",
3118            dialect=dialect,
3119            copy=copy,
3120            **opts,
3121        )

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:
3123    def group_by(
3124        self,
3125        *expressions: t.Optional[ExpOrStr],
3126        append: bool = True,
3127        dialect: DialectType = None,
3128        copy: bool = True,
3129        **opts,
3130    ) -> Select:
3131        """
3132        Set the GROUP BY expression.
3133
3134        Example:
3135            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3136            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3137
3138        Args:
3139            *expressions: the SQL code strings to parse.
3140                If a `Group` instance is passed, this is used as-is.
3141                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3142                If nothing is passed in then a group by is not applied to the expression
3143            append: if `True`, add to any existing expressions.
3144                Otherwise, this flattens all the `Group` expression into a single expression.
3145            dialect: the dialect used to parse the input expression.
3146            copy: if `False`, modify this expression instance in-place.
3147            opts: other options to use to parse the input expressions.
3148
3149        Returns:
3150            The modified Select expression.
3151        """
3152        if not expressions:
3153            return self if not copy else self.copy()
3154
3155        return _apply_child_list_builder(
3156            *expressions,
3157            instance=self,
3158            arg="group",
3159            append=append,
3160            copy=copy,
3161            prefix="GROUP BY",
3162            into=Group,
3163            dialect=dialect,
3164            **opts,
3165        )

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 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:
3167    def sort_by(
3168        self,
3169        *expressions: t.Optional[ExpOrStr],
3170        append: bool = True,
3171        dialect: DialectType = None,
3172        copy: bool = True,
3173        **opts,
3174    ) -> Select:
3175        """
3176        Set the SORT BY expression.
3177
3178        Example:
3179            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3180            'SELECT x FROM tbl SORT BY x DESC'
3181
3182        Args:
3183            *expressions: the SQL code strings to parse.
3184                If a `Group` instance is passed, this is used as-is.
3185                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3186            append: if `True`, add to any existing expressions.
3187                Otherwise, this flattens all the `Order` expression into a single expression.
3188            dialect: the dialect used to parse the input expression.
3189            copy: if `False`, modify this expression instance in-place.
3190            opts: other options to use to parse the input expressions.
3191
3192        Returns:
3193            The modified Select expression.
3194        """
3195        return _apply_child_list_builder(
3196            *expressions,
3197            instance=self,
3198            arg="sort",
3199            append=append,
3200            copy=copy,
3201            prefix="SORT BY",
3202            into=Sort,
3203            dialect=dialect,
3204            **opts,
3205        )

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:
3207    def cluster_by(
3208        self,
3209        *expressions: t.Optional[ExpOrStr],
3210        append: bool = True,
3211        dialect: DialectType = None,
3212        copy: bool = True,
3213        **opts,
3214    ) -> Select:
3215        """
3216        Set the CLUSTER BY expression.
3217
3218        Example:
3219            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3220            'SELECT x FROM tbl CLUSTER BY x DESC'
3221
3222        Args:
3223            *expressions: the SQL code strings to parse.
3224                If a `Group` instance is passed, this is used as-is.
3225                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3226            append: if `True`, add to any existing expressions.
3227                Otherwise, this flattens all the `Order` expression into a single expression.
3228            dialect: the dialect used to parse the input expression.
3229            copy: if `False`, modify this expression instance in-place.
3230            opts: other options to use to parse the input expressions.
3231
3232        Returns:
3233            The modified Select expression.
3234        """
3235        return _apply_child_list_builder(
3236            *expressions,
3237            instance=self,
3238            arg="cluster",
3239            append=append,
3240            copy=copy,
3241            prefix="CLUSTER BY",
3242            into=Cluster,
3243            dialect=dialect,
3244            **opts,
3245        )

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 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:
3247    def select(
3248        self,
3249        *expressions: t.Optional[ExpOrStr],
3250        append: bool = True,
3251        dialect: DialectType = None,
3252        copy: bool = True,
3253        **opts,
3254    ) -> Select:
3255        return _apply_list_builder(
3256            *expressions,
3257            instance=self,
3258            arg="expressions",
3259            append=append,
3260            dialect=dialect,
3261            into=Expression,
3262            copy=copy,
3263            **opts,
3264        )

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:
3266    def lateral(
3267        self,
3268        *expressions: t.Optional[ExpOrStr],
3269        append: bool = True,
3270        dialect: DialectType = None,
3271        copy: bool = True,
3272        **opts,
3273    ) -> Select:
3274        """
3275        Append to or set the LATERAL expressions.
3276
3277        Example:
3278            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3279            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3280
3281        Args:
3282            *expressions: the SQL code strings to parse.
3283                If an `Expression` instance is passed, it will be used as-is.
3284            append: if `True`, add to any existing expressions.
3285                Otherwise, this resets the expressions.
3286            dialect: the dialect used to parse the input expressions.
3287            copy: if `False`, modify this expression instance in-place.
3288            opts: other options to use to parse the input expressions.
3289
3290        Returns:
3291            The modified Select expression.
3292        """
3293        return _apply_list_builder(
3294            *expressions,
3295            instance=self,
3296            arg="laterals",
3297            append=append,
3298            into=Lateral,
3299            prefix="LATERAL VIEW",
3300            dialect=dialect,
3301            copy=copy,
3302            **opts,
3303        )

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:
3305    def join(
3306        self,
3307        expression: ExpOrStr,
3308        on: t.Optional[ExpOrStr] = None,
3309        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3310        append: bool = True,
3311        join_type: t.Optional[str] = None,
3312        join_alias: t.Optional[Identifier | str] = None,
3313        dialect: DialectType = None,
3314        copy: bool = True,
3315        **opts,
3316    ) -> Select:
3317        """
3318        Append to or set the JOIN expressions.
3319
3320        Example:
3321            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3322            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3323
3324            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3325            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3326
3327            Use `join_type` to change the type of join:
3328
3329            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3330            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3331
3332        Args:
3333            expression: the SQL code string to parse.
3334                If an `Expression` instance is passed, it will be used as-is.
3335            on: optionally specify the join "on" criteria as a SQL string.
3336                If an `Expression` instance is passed, it will be used as-is.
3337            using: optionally specify the join "using" criteria as a SQL string.
3338                If an `Expression` instance is passed, it will be used as-is.
3339            append: if `True`, add to any existing expressions.
3340                Otherwise, this resets the expressions.
3341            join_type: if set, alter the parsed join type.
3342            join_alias: an optional alias for the joined source.
3343            dialect: the dialect used to parse the input expressions.
3344            copy: if `False`, modify this expression instance in-place.
3345            opts: other options to use to parse the input expressions.
3346
3347        Returns:
3348            Select: the modified expression.
3349        """
3350        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3351
3352        try:
3353            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3354        except ParseError:
3355            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3356
3357        join = expression if isinstance(expression, Join) else Join(this=expression)
3358
3359        if isinstance(join.this, Select):
3360            join.this.replace(join.this.subquery())
3361
3362        if join_type:
3363            method: t.Optional[Token]
3364            side: t.Optional[Token]
3365            kind: t.Optional[Token]
3366
3367            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3368
3369            if method:
3370                join.set("method", method.text)
3371            if side:
3372                join.set("side", side.text)
3373            if kind:
3374                join.set("kind", kind.text)
3375
3376        if on:
3377            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3378            join.set("on", on)
3379
3380        if using:
3381            join = _apply_list_builder(
3382                *ensure_list(using),
3383                instance=join,
3384                arg="using",
3385                append=append,
3386                copy=copy,
3387                into=Identifier,
3388                **opts,
3389            )
3390
3391        if join_alias:
3392            join.set("this", alias_(join.this, join_alias, table=True))
3393
3394        return _apply_list_builder(
3395            join,
3396            instance=self,
3397            arg="joins",
3398            append=append,
3399            copy=copy,
3400            **opts,
3401        )

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:
3403    def where(
3404        self,
3405        *expressions: t.Optional[ExpOrStr],
3406        append: bool = True,
3407        dialect: DialectType = None,
3408        copy: bool = True,
3409        **opts,
3410    ) -> Select:
3411        """
3412        Append to or set the WHERE expressions.
3413
3414        Example:
3415            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3416            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3417
3418        Args:
3419            *expressions: the SQL code strings to parse.
3420                If an `Expression` instance is passed, it will be used as-is.
3421                Multiple expressions are combined with an AND operator.
3422            append: if `True`, AND the new expressions to any existing expression.
3423                Otherwise, this resets the expression.
3424            dialect: the dialect used to parse the input expressions.
3425            copy: if `False`, modify this expression instance in-place.
3426            opts: other options to use to parse the input expressions.
3427
3428        Returns:
3429            Select: the modified expression.
3430        """
3431        return _apply_conjunction_builder(
3432            *expressions,
3433            instance=self,
3434            arg="where",
3435            append=append,
3436            into=Where,
3437            dialect=dialect,
3438            copy=copy,
3439            **opts,
3440        )

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:
3442    def having(
3443        self,
3444        *expressions: t.Optional[ExpOrStr],
3445        append: bool = True,
3446        dialect: DialectType = None,
3447        copy: bool = True,
3448        **opts,
3449    ) -> Select:
3450        """
3451        Append to or set the HAVING expressions.
3452
3453        Example:
3454            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3455            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3456
3457        Args:
3458            *expressions: the SQL code strings to parse.
3459                If an `Expression` instance is passed, it will be used as-is.
3460                Multiple expressions are combined with an AND operator.
3461            append: if `True`, AND the new expressions to any existing expression.
3462                Otherwise, this resets the expression.
3463            dialect: the dialect used to parse the input expressions.
3464            copy: if `False`, modify this expression instance in-place.
3465            opts: other options to use to parse the input expressions.
3466
3467        Returns:
3468            The modified Select expression.
3469        """
3470        return _apply_conjunction_builder(
3471            *expressions,
3472            instance=self,
3473            arg="having",
3474            append=append,
3475            into=Having,
3476            dialect=dialect,
3477            copy=copy,
3478            **opts,
3479        )

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:
3481    def window(
3482        self,
3483        *expressions: t.Optional[ExpOrStr],
3484        append: bool = True,
3485        dialect: DialectType = None,
3486        copy: bool = True,
3487        **opts,
3488    ) -> Select:
3489        return _apply_list_builder(
3490            *expressions,
3491            instance=self,
3492            arg="windows",
3493            append=append,
3494            into=Window,
3495            dialect=dialect,
3496            copy=copy,
3497            **opts,
3498        )
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:
3500    def qualify(
3501        self,
3502        *expressions: t.Optional[ExpOrStr],
3503        append: bool = True,
3504        dialect: DialectType = None,
3505        copy: bool = True,
3506        **opts,
3507    ) -> Select:
3508        return _apply_conjunction_builder(
3509            *expressions,
3510            instance=self,
3511            arg="qualify",
3512            append=append,
3513            into=Qualify,
3514            dialect=dialect,
3515            copy=copy,
3516            **opts,
3517        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3519    def distinct(
3520        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3521    ) -> Select:
3522        """
3523        Set the OFFSET expression.
3524
3525        Example:
3526            >>> Select().from_("tbl").select("x").distinct().sql()
3527            'SELECT DISTINCT x FROM tbl'
3528
3529        Args:
3530            ons: the expressions to distinct on
3531            distinct: whether the Select should be distinct
3532            copy: if `False`, modify this expression instance in-place.
3533
3534        Returns:
3535            Select: the modified expression.
3536        """
3537        instance = maybe_copy(self, copy)
3538        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3539        instance.set("distinct", Distinct(on=on) if distinct else None)
3540        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:
3542    def ctas(
3543        self,
3544        table: ExpOrStr,
3545        properties: t.Optional[t.Dict] = None,
3546        dialect: DialectType = None,
3547        copy: bool = True,
3548        **opts,
3549    ) -> Create:
3550        """
3551        Convert this expression to a CREATE TABLE AS statement.
3552
3553        Example:
3554            >>> Select().select("*").from_("tbl").ctas("x").sql()
3555            'CREATE TABLE x AS SELECT * FROM tbl'
3556
3557        Args:
3558            table: the SQL code string to parse as the table name.
3559                If another `Expression` instance is passed, it will be used as-is.
3560            properties: an optional mapping of table properties
3561            dialect: the dialect used to parse the input table.
3562            copy: if `False`, modify this expression instance in-place.
3563            opts: other options to use to parse the input table.
3564
3565        Returns:
3566            The new Create expression.
3567        """
3568        instance = maybe_copy(self, copy)
3569        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3570
3571        properties_expression = None
3572        if properties:
3573            properties_expression = Properties.from_dict(properties)
3574
3575        return Create(
3576            this=table_expression,
3577            kind="TABLE",
3578            expression=instance,
3579            properties=properties_expression,
3580        )

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:
3582    def lock(self, update: bool = True, copy: bool = True) -> Select:
3583        """
3584        Set the locking read mode for this expression.
3585
3586        Examples:
3587            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3588            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3589
3590            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3591            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3592
3593        Args:
3594            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3595            copy: if `False`, modify this expression instance in-place.
3596
3597        Returns:
3598            The modified expression.
3599        """
3600        inst = maybe_copy(self, copy)
3601        inst.set("locks", [Lock(update=update)])
3602
3603        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:
3605    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3606        """
3607        Set hints for this expression.
3608
3609        Examples:
3610            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3611            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3612
3613        Args:
3614            hints: The SQL code strings to parse as the hints.
3615                If an `Expression` instance is passed, it will be used as-is.
3616            dialect: The dialect used to parse the hints.
3617            copy: If `False`, modify this expression instance in-place.
3618
3619        Returns:
3620            The modified expression.
3621        """
3622        inst = maybe_copy(self, copy)
3623        inst.set(
3624            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3625        )
3626
3627        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]
3629    @property
3630    def named_selects(self) -> t.List[str]:
3631        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
3633    @property
3634    def is_star(self) -> bool:
3635        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3637    @property
3638    def selects(self) -> t.List[Expression]:
3639        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3645class Subquery(DerivedTable, Query):
3646    arg_types = {
3647        "this": True,
3648        "alias": False,
3649        "with": False,
3650        **QUERY_MODIFIERS,
3651    }
3652
3653    def unnest(self):
3654        """Returns the first non subquery."""
3655        expression = self
3656        while isinstance(expression, Subquery):
3657            expression = expression.this
3658        return expression
3659
3660    def unwrap(self) -> Subquery:
3661        expression = self
3662        while expression.same_parent and expression.is_wrapper:
3663            expression = t.cast(Subquery, expression.parent)
3664        return expression
3665
3666    def select(
3667        self,
3668        *expressions: t.Optional[ExpOrStr],
3669        append: bool = True,
3670        dialect: DialectType = None,
3671        copy: bool = True,
3672        **opts,
3673    ) -> Subquery:
3674        this = maybe_copy(self, copy)
3675        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3676        return this
3677
3678    @property
3679    def is_wrapper(self) -> bool:
3680        """
3681        Whether this Subquery acts as a simple wrapper around another expression.
3682
3683        SELECT * FROM (((SELECT * FROM t)))
3684                      ^
3685                      This corresponds to a "wrapper" Subquery node
3686        """
3687        return all(v is None for k, v in self.args.items() if k != "this")
3688
3689    @property
3690    def is_star(self) -> bool:
3691        return self.this.is_star
3692
3693    @property
3694    def output_name(self) -> str:
3695        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):
3653    def unnest(self):
3654        """Returns the first non subquery."""
3655        expression = self
3656        while isinstance(expression, Subquery):
3657            expression = expression.this
3658        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3660    def unwrap(self) -> Subquery:
3661        expression = self
3662        while expression.same_parent and expression.is_wrapper:
3663            expression = t.cast(Subquery, expression.parent)
3664        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:
3666    def select(
3667        self,
3668        *expressions: t.Optional[ExpOrStr],
3669        append: bool = True,
3670        dialect: DialectType = None,
3671        copy: bool = True,
3672        **opts,
3673    ) -> Subquery:
3674        this = maybe_copy(self, copy)
3675        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3676        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
3678    @property
3679    def is_wrapper(self) -> bool:
3680        """
3681        Whether this Subquery acts as a simple wrapper around another expression.
3682
3683        SELECT * FROM (((SELECT * FROM t)))
3684                      ^
3685                      This corresponds to a "wrapper" Subquery node
3686        """
3687        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
3689    @property
3690    def is_star(self) -> bool:
3691        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3693    @property
3694    def output_name(self) -> str:
3695        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):
3698class TableSample(Expression):
3699    arg_types = {
3700        "this": False,
3701        "expressions": False,
3702        "method": False,
3703        "bucket_numerator": False,
3704        "bucket_denominator": False,
3705        "bucket_field": False,
3706        "percent": False,
3707        "rows": False,
3708        "size": False,
3709        "seed": False,
3710    }
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):
3713class Tag(Expression):
3714    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3715
3716    arg_types = {
3717        "this": False,
3718        "prefix": False,
3719        "postfix": False,
3720    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3725class Pivot(Expression):
3726    arg_types = {
3727        "this": False,
3728        "alias": False,
3729        "expressions": False,
3730        "field": False,
3731        "unpivot": False,
3732        "using": False,
3733        "group": False,
3734        "columns": False,
3735        "include_nulls": False,
3736    }
3737
3738    @property
3739    def unpivot(self) -> bool:
3740        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
3738    @property
3739    def unpivot(self) -> bool:
3740        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3743class Window(Condition):
3744    arg_types = {
3745        "this": True,
3746        "partition_by": False,
3747        "order": False,
3748        "spec": False,
3749        "alias": False,
3750        "over": False,
3751        "first": False,
3752    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3755class WindowSpec(Expression):
3756    arg_types = {
3757        "kind": False,
3758        "start": False,
3759        "start_side": False,
3760        "end": False,
3761        "end_side": False,
3762    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3765class PreWhere(Expression):
3766    pass
key = 'prewhere'
class Where(Expression):
3769class Where(Expression):
3770    pass
key = 'where'
class Star(Expression):
3773class Star(Expression):
3774    arg_types = {"except": False, "replace": False}
3775
3776    @property
3777    def name(self) -> str:
3778        return "*"
3779
3780    @property
3781    def output_name(self) -> str:
3782        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3776    @property
3777    def name(self) -> str:
3778        return "*"
output_name: str
3780    @property
3781    def output_name(self) -> str:
3782        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):
3785class Parameter(Condition):
3786    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3789class SessionParameter(Condition):
3790    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3793class Placeholder(Condition):
3794    arg_types = {"this": False, "kind": False}
3795
3796    @property
3797    def name(self) -> str:
3798        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3796    @property
3797    def name(self) -> str:
3798        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3801class Null(Condition):
3802    arg_types: t.Dict[str, t.Any] = {}
3803
3804    @property
3805    def name(self) -> str:
3806        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3804    @property
3805    def name(self) -> str:
3806        return "NULL"
key = 'null'
class Boolean(Condition):
3809class Boolean(Condition):
3810    pass
key = 'boolean'
class DataTypeParam(Expression):
3813class DataTypeParam(Expression):
3814    arg_types = {"this": True, "expression": False}
3815
3816    @property
3817    def name(self) -> str:
3818        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3816    @property
3817    def name(self) -> str:
3818        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3821class DataType(Expression):
3822    arg_types = {
3823        "this": True,
3824        "expressions": False,
3825        "nested": False,
3826        "values": False,
3827        "prefix": False,
3828        "kind": False,
3829    }
3830
3831    class Type(AutoName):
3832        ARRAY = auto()
3833        AGGREGATEFUNCTION = auto()
3834        SIMPLEAGGREGATEFUNCTION = auto()
3835        BIGDECIMAL = auto()
3836        BIGINT = auto()
3837        BIGSERIAL = auto()
3838        BINARY = auto()
3839        BIT = auto()
3840        BOOLEAN = auto()
3841        BPCHAR = auto()
3842        CHAR = auto()
3843        DATE = auto()
3844        DATE32 = auto()
3845        DATEMULTIRANGE = auto()
3846        DATERANGE = auto()
3847        DATETIME = auto()
3848        DATETIME64 = auto()
3849        DECIMAL = auto()
3850        DOUBLE = auto()
3851        ENUM = auto()
3852        ENUM8 = auto()
3853        ENUM16 = auto()
3854        FIXEDSTRING = auto()
3855        FLOAT = auto()
3856        GEOGRAPHY = auto()
3857        GEOMETRY = auto()
3858        HLLSKETCH = auto()
3859        HSTORE = auto()
3860        IMAGE = auto()
3861        INET = auto()
3862        INT = auto()
3863        INT128 = auto()
3864        INT256 = auto()
3865        INT4MULTIRANGE = auto()
3866        INT4RANGE = auto()
3867        INT8MULTIRANGE = auto()
3868        INT8RANGE = auto()
3869        INTERVAL = auto()
3870        IPADDRESS = auto()
3871        IPPREFIX = auto()
3872        IPV4 = auto()
3873        IPV6 = auto()
3874        JSON = auto()
3875        JSONB = auto()
3876        LONGBLOB = auto()
3877        LONGTEXT = auto()
3878        LOWCARDINALITY = auto()
3879        MAP = auto()
3880        MEDIUMBLOB = auto()
3881        MEDIUMINT = auto()
3882        MEDIUMTEXT = auto()
3883        MONEY = auto()
3884        NAME = auto()
3885        NCHAR = auto()
3886        NESTED = auto()
3887        NULL = auto()
3888        NULLABLE = auto()
3889        NUMMULTIRANGE = auto()
3890        NUMRANGE = auto()
3891        NVARCHAR = auto()
3892        OBJECT = auto()
3893        ROWVERSION = auto()
3894        SERIAL = auto()
3895        SET = auto()
3896        SMALLINT = auto()
3897        SMALLMONEY = auto()
3898        SMALLSERIAL = auto()
3899        STRUCT = auto()
3900        SUPER = auto()
3901        TEXT = auto()
3902        TINYBLOB = auto()
3903        TINYTEXT = auto()
3904        TIME = auto()
3905        TIMETZ = auto()
3906        TIMESTAMP = auto()
3907        TIMESTAMPLTZ = auto()
3908        TIMESTAMPTZ = auto()
3909        TIMESTAMP_S = auto()
3910        TIMESTAMP_MS = auto()
3911        TIMESTAMP_NS = auto()
3912        TINYINT = auto()
3913        TSMULTIRANGE = auto()
3914        TSRANGE = auto()
3915        TSTZMULTIRANGE = auto()
3916        TSTZRANGE = auto()
3917        UBIGINT = auto()
3918        UINT = auto()
3919        UINT128 = auto()
3920        UINT256 = auto()
3921        UMEDIUMINT = auto()
3922        UDECIMAL = auto()
3923        UNIQUEIDENTIFIER = auto()
3924        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3925        USERDEFINED = "USER-DEFINED"
3926        USMALLINT = auto()
3927        UTINYINT = auto()
3928        UUID = auto()
3929        VARBINARY = auto()
3930        VARCHAR = auto()
3931        VARIANT = auto()
3932        XML = auto()
3933        YEAR = auto()
3934
3935    STRUCT_TYPES = {
3936        Type.NESTED,
3937        Type.OBJECT,
3938        Type.STRUCT,
3939    }
3940
3941    NESTED_TYPES = {
3942        *STRUCT_TYPES,
3943        Type.ARRAY,
3944        Type.MAP,
3945    }
3946
3947    TEXT_TYPES = {
3948        Type.CHAR,
3949        Type.NCHAR,
3950        Type.NVARCHAR,
3951        Type.TEXT,
3952        Type.VARCHAR,
3953        Type.NAME,
3954    }
3955
3956    SIGNED_INTEGER_TYPES = {
3957        Type.BIGINT,
3958        Type.INT,
3959        Type.INT128,
3960        Type.INT256,
3961        Type.MEDIUMINT,
3962        Type.SMALLINT,
3963        Type.TINYINT,
3964    }
3965
3966    UNSIGNED_INTEGER_TYPES = {
3967        Type.UBIGINT,
3968        Type.UINT,
3969        Type.UINT128,
3970        Type.UINT256,
3971        Type.UMEDIUMINT,
3972        Type.USMALLINT,
3973        Type.UTINYINT,
3974    }
3975
3976    INTEGER_TYPES = {
3977        *SIGNED_INTEGER_TYPES,
3978        *UNSIGNED_INTEGER_TYPES,
3979        Type.BIT,
3980    }
3981
3982    FLOAT_TYPES = {
3983        Type.DOUBLE,
3984        Type.FLOAT,
3985    }
3986
3987    REAL_TYPES = {
3988        *FLOAT_TYPES,
3989        Type.BIGDECIMAL,
3990        Type.DECIMAL,
3991        Type.MONEY,
3992        Type.SMALLMONEY,
3993        Type.UDECIMAL,
3994    }
3995
3996    NUMERIC_TYPES = {
3997        *INTEGER_TYPES,
3998        *REAL_TYPES,
3999    }
4000
4001    TEMPORAL_TYPES = {
4002        Type.DATE,
4003        Type.DATE32,
4004        Type.DATETIME,
4005        Type.DATETIME64,
4006        Type.TIME,
4007        Type.TIMESTAMP,
4008        Type.TIMESTAMPLTZ,
4009        Type.TIMESTAMPTZ,
4010        Type.TIMESTAMP_MS,
4011        Type.TIMESTAMP_NS,
4012        Type.TIMESTAMP_S,
4013        Type.TIMETZ,
4014    }
4015
4016    @classmethod
4017    def build(
4018        cls,
4019        dtype: DATA_TYPE,
4020        dialect: DialectType = None,
4021        udt: bool = False,
4022        copy: bool = True,
4023        **kwargs,
4024    ) -> DataType:
4025        """
4026        Constructs a DataType object.
4027
4028        Args:
4029            dtype: the data type of interest.
4030            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4031            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4032                DataType, thus creating a user-defined type.
4033            copy: whether to copy the data type.
4034            kwargs: additional arguments to pass in the constructor of DataType.
4035
4036        Returns:
4037            The constructed DataType object.
4038        """
4039        from sqlglot import parse_one
4040
4041        if isinstance(dtype, str):
4042            if dtype.upper() == "UNKNOWN":
4043                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4044
4045            try:
4046                data_type_exp = parse_one(
4047                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4048                )
4049            except ParseError:
4050                if udt:
4051                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4052                raise
4053        elif isinstance(dtype, DataType.Type):
4054            data_type_exp = DataType(this=dtype)
4055        elif isinstance(dtype, DataType):
4056            return maybe_copy(dtype, copy)
4057        else:
4058            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4059
4060        return DataType(**{**data_type_exp.args, **kwargs})
4061
4062    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4063        """
4064        Checks whether this DataType matches one of the provided data types. Nested types or precision
4065        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4066
4067        Args:
4068            dtypes: the data types to compare this DataType to.
4069
4070        Returns:
4071            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4072        """
4073        for dtype in dtypes:
4074            other = DataType.build(dtype, copy=False, udt=True)
4075
4076            if (
4077                other.expressions
4078                or self.this == DataType.Type.USERDEFINED
4079                or other.this == DataType.Type.USERDEFINED
4080            ):
4081                matches = self == other
4082            else:
4083                matches = self.this == other.this
4084
4085            if matches:
4086                return True
4087        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.MAP: 'MAP'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.INT128: 'INT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
NUMERIC_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.INT128: 'INT128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.MONEY: 'MONEY'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <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:
4016    @classmethod
4017    def build(
4018        cls,
4019        dtype: DATA_TYPE,
4020        dialect: DialectType = None,
4021        udt: bool = False,
4022        copy: bool = True,
4023        **kwargs,
4024    ) -> DataType:
4025        """
4026        Constructs a DataType object.
4027
4028        Args:
4029            dtype: the data type of interest.
4030            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4031            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4032                DataType, thus creating a user-defined type.
4033            copy: whether to copy the data type.
4034            kwargs: additional arguments to pass in the constructor of DataType.
4035
4036        Returns:
4037            The constructed DataType object.
4038        """
4039        from sqlglot import parse_one
4040
4041        if isinstance(dtype, str):
4042            if dtype.upper() == "UNKNOWN":
4043                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4044
4045            try:
4046                data_type_exp = parse_one(
4047                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4048                )
4049            except ParseError:
4050                if udt:
4051                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4052                raise
4053        elif isinstance(dtype, DataType.Type):
4054            data_type_exp = DataType(this=dtype)
4055        elif isinstance(dtype, DataType):
4056            return maybe_copy(dtype, copy)
4057        else:
4058            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4059
4060        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:
4062    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4063        """
4064        Checks whether this DataType matches one of the provided data types. Nested types or precision
4065        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4066
4067        Args:
4068            dtypes: the data types to compare this DataType to.
4069
4070        Returns:
4071            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4072        """
4073        for dtype in dtypes:
4074            other = DataType.build(dtype, copy=False, udt=True)
4075
4076            if (
4077                other.expressions
4078                or self.this == DataType.Type.USERDEFINED
4079                or other.this == DataType.Type.USERDEFINED
4080            ):
4081                matches = self == other
4082            else:
4083                matches = self.this == other.this
4084
4085            if matches:
4086                return True
4087        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):
3831    class Type(AutoName):
3832        ARRAY = auto()
3833        AGGREGATEFUNCTION = auto()
3834        SIMPLEAGGREGATEFUNCTION = auto()
3835        BIGDECIMAL = auto()
3836        BIGINT = auto()
3837        BIGSERIAL = auto()
3838        BINARY = auto()
3839        BIT = auto()
3840        BOOLEAN = auto()
3841        BPCHAR = auto()
3842        CHAR = auto()
3843        DATE = auto()
3844        DATE32 = auto()
3845        DATEMULTIRANGE = auto()
3846        DATERANGE = auto()
3847        DATETIME = auto()
3848        DATETIME64 = auto()
3849        DECIMAL = auto()
3850        DOUBLE = auto()
3851        ENUM = auto()
3852        ENUM8 = auto()
3853        ENUM16 = auto()
3854        FIXEDSTRING = auto()
3855        FLOAT = auto()
3856        GEOGRAPHY = auto()
3857        GEOMETRY = auto()
3858        HLLSKETCH = auto()
3859        HSTORE = auto()
3860        IMAGE = auto()
3861        INET = auto()
3862        INT = auto()
3863        INT128 = auto()
3864        INT256 = auto()
3865        INT4MULTIRANGE = auto()
3866        INT4RANGE = auto()
3867        INT8MULTIRANGE = auto()
3868        INT8RANGE = auto()
3869        INTERVAL = auto()
3870        IPADDRESS = auto()
3871        IPPREFIX = auto()
3872        IPV4 = auto()
3873        IPV6 = auto()
3874        JSON = auto()
3875        JSONB = auto()
3876        LONGBLOB = auto()
3877        LONGTEXT = auto()
3878        LOWCARDINALITY = auto()
3879        MAP = auto()
3880        MEDIUMBLOB = auto()
3881        MEDIUMINT = auto()
3882        MEDIUMTEXT = auto()
3883        MONEY = auto()
3884        NAME = auto()
3885        NCHAR = auto()
3886        NESTED = auto()
3887        NULL = auto()
3888        NULLABLE = auto()
3889        NUMMULTIRANGE = auto()
3890        NUMRANGE = auto()
3891        NVARCHAR = auto()
3892        OBJECT = auto()
3893        ROWVERSION = auto()
3894        SERIAL = auto()
3895        SET = auto()
3896        SMALLINT = auto()
3897        SMALLMONEY = auto()
3898        SMALLSERIAL = auto()
3899        STRUCT = auto()
3900        SUPER = auto()
3901        TEXT = auto()
3902        TINYBLOB = auto()
3903        TINYTEXT = auto()
3904        TIME = auto()
3905        TIMETZ = auto()
3906        TIMESTAMP = auto()
3907        TIMESTAMPLTZ = auto()
3908        TIMESTAMPTZ = auto()
3909        TIMESTAMP_S = auto()
3910        TIMESTAMP_MS = auto()
3911        TIMESTAMP_NS = auto()
3912        TINYINT = auto()
3913        TSMULTIRANGE = auto()
3914        TSRANGE = auto()
3915        TSTZMULTIRANGE = auto()
3916        TSTZRANGE = auto()
3917        UBIGINT = auto()
3918        UINT = auto()
3919        UINT128 = auto()
3920        UINT256 = auto()
3921        UMEDIUMINT = auto()
3922        UDECIMAL = auto()
3923        UNIQUEIDENTIFIER = auto()
3924        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3925        USERDEFINED = "USER-DEFINED"
3926        USMALLINT = auto()
3927        UTINYINT = auto()
3928        UUID = auto()
3929        VARBINARY = auto()
3930        VARCHAR = auto()
3931        VARIANT = auto()
3932        XML = auto()
3933        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NAME = <Type.NAME: 'NAME'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4094class PseudoType(DataType):
4095    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4099class ObjectIdentifier(DataType):
4100    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4104class SubqueryPredicate(Predicate):
4105    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4108class All(SubqueryPredicate):
4109    pass
key = 'all'
class Any(SubqueryPredicate):
4112class Any(SubqueryPredicate):
4113    pass
key = 'any'
class Exists(SubqueryPredicate):
4116class Exists(SubqueryPredicate):
4117    pass
key = 'exists'
class Command(Expression):
4122class Command(Expression):
4123    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4126class Transaction(Expression):
4127    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4130class Commit(Expression):
4131    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4134class Rollback(Expression):
4135    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4138class AlterTable(Expression):
4139    arg_types = {
4140        "this": True,
4141        "actions": True,
4142        "exists": False,
4143        "only": False,
4144        "options": False,
4145    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4148class AddConstraint(Expression):
4149    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4152class DropPartition(Expression):
4153    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4157class Binary(Condition):
4158    arg_types = {"this": True, "expression": True}
4159
4160    @property
4161    def left(self) -> Expression:
4162        return self.this
4163
4164    @property
4165    def right(self) -> Expression:
4166        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4160    @property
4161    def left(self) -> Expression:
4162        return self.this
right: Expression
4164    @property
4165    def right(self) -> Expression:
4166        return self.expression
key = 'binary'
class Add(Binary):
4169class Add(Binary):
4170    pass
key = 'add'
class Connector(Binary):
4173class Connector(Binary):
4174    pass
key = 'connector'
class And(Connector):
4177class And(Connector):
4178    pass
key = 'and'
class Or(Connector):
4181class Or(Connector):
4182    pass
key = 'or'
class BitwiseAnd(Binary):
4185class BitwiseAnd(Binary):
4186    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4189class BitwiseLeftShift(Binary):
4190    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4193class BitwiseOr(Binary):
4194    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4197class BitwiseRightShift(Binary):
4198    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4201class BitwiseXor(Binary):
4202    pass
key = 'bitwisexor'
class Div(Binary):
4205class Div(Binary):
4206    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):
4209class Overlaps(Binary):
4210    pass
key = 'overlaps'
class Dot(Binary):
4213class Dot(Binary):
4214    @property
4215    def is_star(self) -> bool:
4216        return self.expression.is_star
4217
4218    @property
4219    def name(self) -> str:
4220        return self.expression.name
4221
4222    @property
4223    def output_name(self) -> str:
4224        return self.name
4225
4226    @classmethod
4227    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4228        """Build a Dot object with a sequence of expressions."""
4229        if len(expressions) < 2:
4230            raise ValueError("Dot requires >= 2 expressions.")
4231
4232        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4233
4234    @property
4235    def parts(self) -> t.List[Expression]:
4236        """Return the parts of a table / column in order catalog, db, table."""
4237        this, *parts = self.flatten()
4238
4239        parts.reverse()
4240
4241        for arg in COLUMN_PARTS:
4242            part = this.args.get(arg)
4243
4244            if isinstance(part, Expression):
4245                parts.append(part)
4246
4247        parts.reverse()
4248        return parts
is_star: bool
4214    @property
4215    def is_star(self) -> bool:
4216        return self.expression.is_star

Checks whether an expression is a star.

name: str
4218    @property
4219    def name(self) -> str:
4220        return self.expression.name
output_name: str
4222    @property
4223    def output_name(self) -> str:
4224        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:
4226    @classmethod
4227    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4228        """Build a Dot object with a sequence of expressions."""
4229        if len(expressions) < 2:
4230            raise ValueError("Dot requires >= 2 expressions.")
4231
4232        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]
4234    @property
4235    def parts(self) -> t.List[Expression]:
4236        """Return the parts of a table / column in order catalog, db, table."""
4237        this, *parts = self.flatten()
4238
4239        parts.reverse()
4240
4241        for arg in COLUMN_PARTS:
4242            part = this.args.get(arg)
4243
4244            if isinstance(part, Expression):
4245                parts.append(part)
4246
4247        parts.reverse()
4248        return parts

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

key = 'dot'
class DPipe(Binary):
4251class DPipe(Binary):
4252    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4255class EQ(Binary, Predicate):
4256    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4259class NullSafeEQ(Binary, Predicate):
4260    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4263class NullSafeNEQ(Binary, Predicate):
4264    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4268class PropertyEQ(Binary):
4269    pass
key = 'propertyeq'
class Distance(Binary):
4272class Distance(Binary):
4273    pass
key = 'distance'
class Escape(Binary):
4276class Escape(Binary):
4277    pass
key = 'escape'
class Glob(Binary, Predicate):
4280class Glob(Binary, Predicate):
4281    pass
key = 'glob'
class GT(Binary, Predicate):
4284class GT(Binary, Predicate):
4285    pass
key = 'gt'
class GTE(Binary, Predicate):
4288class GTE(Binary, Predicate):
4289    pass
key = 'gte'
class ILike(Binary, Predicate):
4292class ILike(Binary, Predicate):
4293    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4296class ILikeAny(Binary, Predicate):
4297    pass
key = 'ilikeany'
class IntDiv(Binary):
4300class IntDiv(Binary):
4301    pass
key = 'intdiv'
class Is(Binary, Predicate):
4304class Is(Binary, Predicate):
4305    pass
key = 'is'
class Kwarg(Binary):
4308class Kwarg(Binary):
4309    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4312class Like(Binary, Predicate):
4313    pass
key = 'like'
class LikeAny(Binary, Predicate):
4316class LikeAny(Binary, Predicate):
4317    pass
key = 'likeany'
class LT(Binary, Predicate):
4320class LT(Binary, Predicate):
4321    pass
key = 'lt'
class LTE(Binary, Predicate):
4324class LTE(Binary, Predicate):
4325    pass
key = 'lte'
class Mod(Binary):
4328class Mod(Binary):
4329    pass
key = 'mod'
class Mul(Binary):
4332class Mul(Binary):
4333    pass
key = 'mul'
class NEQ(Binary, Predicate):
4336class NEQ(Binary, Predicate):
4337    pass
key = 'neq'
class Operator(Binary):
4341class Operator(Binary):
4342    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4345class SimilarTo(Binary, Predicate):
4346    pass
key = 'similarto'
class Slice(Binary):
4349class Slice(Binary):
4350    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4353class Sub(Binary):
4354    pass
key = 'sub'
class Unary(Condition):
4359class Unary(Condition):
4360    pass
key = 'unary'
class BitwiseNot(Unary):
4363class BitwiseNot(Unary):
4364    pass
key = 'bitwisenot'
class Not(Unary):
4367class Not(Unary):
4368    pass
key = 'not'
class Paren(Unary):
4371class Paren(Unary):
4372    @property
4373    def output_name(self) -> str:
4374        return self.this.name
output_name: str
4372    @property
4373    def output_name(self) -> str:
4374        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):
4377class Neg(Unary):
4378    pass
key = 'neg'
class Alias(Expression):
4381class Alias(Expression):
4382    arg_types = {"this": True, "alias": False}
4383
4384    @property
4385    def output_name(self) -> str:
4386        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4384    @property
4385    def output_name(self) -> str:
4386        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):
4391class PivotAlias(Alias):
4392    pass
key = 'pivotalias'
class Aliases(Expression):
4395class Aliases(Expression):
4396    arg_types = {"this": True, "expressions": True}
4397
4398    @property
4399    def aliases(self):
4400        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4398    @property
4399    def aliases(self):
4400        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4404class AtIndex(Expression):
4405    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4408class AtTimeZone(Expression):
4409    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4412class FromTimeZone(Expression):
4413    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4416class Between(Predicate):
4417    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4420class Bracket(Condition):
4421    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4422    arg_types = {
4423        "this": True,
4424        "expressions": True,
4425        "offset": False,
4426        "safe": False,
4427        "returns_list_for_maps": False,
4428    }
4429
4430    @property
4431    def output_name(self) -> str:
4432        if len(self.expressions) == 1:
4433            return self.expressions[0].output_name
4434
4435        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4430    @property
4431    def output_name(self) -> str:
4432        if len(self.expressions) == 1:
4433            return self.expressions[0].output_name
4434
4435        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):
4438class Distinct(Expression):
4439    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4442class In(Predicate):
4443    arg_types = {
4444        "this": True,
4445        "expressions": False,
4446        "query": False,
4447        "unnest": False,
4448        "field": False,
4449        "is_global": False,
4450    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4454class ForIn(Expression):
4455    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4458class TimeUnit(Expression):
4459    """Automatically converts unit arg into a var."""
4460
4461    arg_types = {"unit": False}
4462
4463    UNABBREVIATED_UNIT_NAME = {
4464        "D": "DAY",
4465        "H": "HOUR",
4466        "M": "MINUTE",
4467        "MS": "MILLISECOND",
4468        "NS": "NANOSECOND",
4469        "Q": "QUARTER",
4470        "S": "SECOND",
4471        "US": "MICROSECOND",
4472        "W": "WEEK",
4473        "Y": "YEAR",
4474    }
4475
4476    VAR_LIKE = (Column, Literal, Var)
4477
4478    def __init__(self, **args):
4479        unit = args.get("unit")
4480        if isinstance(unit, self.VAR_LIKE):
4481            args["unit"] = Var(
4482                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4483            )
4484        elif isinstance(unit, Week):
4485            unit.set("this", Var(this=unit.this.name.upper()))
4486
4487        super().__init__(**args)
4488
4489    @property
4490    def unit(self) -> t.Optional[Var | IntervalSpan]:
4491        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4478    def __init__(self, **args):
4479        unit = args.get("unit")
4480        if isinstance(unit, self.VAR_LIKE):
4481            args["unit"] = Var(
4482                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4483            )
4484        elif isinstance(unit, Week):
4485            unit.set("this", Var(this=unit.this.name.upper()))
4486
4487        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: Union[Var, IntervalSpan, NoneType]
4489    @property
4490    def unit(self) -> t.Optional[Var | IntervalSpan]:
4491        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4494class IntervalOp(TimeUnit):
4495    arg_types = {"unit": True, "expression": True}
4496
4497    def interval(self):
4498        return Interval(
4499            this=self.expression.copy(),
4500            unit=self.unit.copy(),
4501        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4497    def interval(self):
4498        return Interval(
4499            this=self.expression.copy(),
4500            unit=self.unit.copy(),
4501        )
key = 'intervalop'
class IntervalSpan(DataType):
4507class IntervalSpan(DataType):
4508    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4511class Interval(TimeUnit):
4512    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4515class IgnoreNulls(Expression):
4516    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4519class RespectNulls(Expression):
4520    pass
key = 'respectnulls'
class HavingMax(Expression):
4524class HavingMax(Expression):
4525    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4529class Func(Condition):
4530    """
4531    The base class for all function expressions.
4532
4533    Attributes:
4534        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4535            treated as a variable length argument and the argument's value will be stored as a list.
4536        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4537            function expression. These values are used to map this node to a name during parsing as
4538            well as to provide the function's name during SQL string generation. By default the SQL
4539            name is set to the expression's class name transformed to snake case.
4540    """
4541
4542    is_var_len_args = False
4543
4544    @classmethod
4545    def from_arg_list(cls, args):
4546        if cls.is_var_len_args:
4547            all_arg_keys = list(cls.arg_types)
4548            # If this function supports variable length argument treat the last argument as such.
4549            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4550            num_non_var = len(non_var_len_arg_keys)
4551
4552            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4553            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4554        else:
4555            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4556
4557        return cls(**args_dict)
4558
4559    @classmethod
4560    def sql_names(cls):
4561        if cls is Func:
4562            raise NotImplementedError(
4563                "SQL name is only supported by concrete function implementations"
4564            )
4565        if "_sql_names" not in cls.__dict__:
4566            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4567        return cls._sql_names
4568
4569    @classmethod
4570    def sql_name(cls):
4571        return cls.sql_names()[0]
4572
4573    @classmethod
4574    def default_parser_mappings(cls):
4575        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):
4544    @classmethod
4545    def from_arg_list(cls, args):
4546        if cls.is_var_len_args:
4547            all_arg_keys = list(cls.arg_types)
4548            # If this function supports variable length argument treat the last argument as such.
4549            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4550            num_non_var = len(non_var_len_arg_keys)
4551
4552            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4553            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4554        else:
4555            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4556
4557        return cls(**args_dict)
@classmethod
def sql_names(cls):
4559    @classmethod
4560    def sql_names(cls):
4561        if cls is Func:
4562            raise NotImplementedError(
4563                "SQL name is only supported by concrete function implementations"
4564            )
4565        if "_sql_names" not in cls.__dict__:
4566            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4567        return cls._sql_names
@classmethod
def sql_name(cls):
4569    @classmethod
4570    def sql_name(cls):
4571        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4573    @classmethod
4574    def default_parser_mappings(cls):
4575        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4578class AggFunc(Func):
4579    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4582class ParameterizedAgg(AggFunc):
4583    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4586class Abs(Func):
4587    pass
key = 'abs'
class ArgMax(AggFunc):
4590class ArgMax(AggFunc):
4591    arg_types = {"this": True, "expression": True, "count": False}
4592    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4595class ArgMin(AggFunc):
4596    arg_types = {"this": True, "expression": True, "count": False}
4597    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4600class ApproxTopK(AggFunc):
4601    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4604class Flatten(Func):
4605    pass
key = 'flatten'
class Transform(Func):
4609class Transform(Func):
4610    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4613class Anonymous(Func):
4614    arg_types = {"this": True, "expressions": False}
4615    is_var_len_args = True
4616
4617    @property
4618    def name(self) -> str:
4619        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
4617    @property
4618    def name(self) -> str:
4619        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4622class AnonymousAggFunc(AggFunc):
4623    arg_types = {"this": True, "expressions": False}
4624    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4628class CombinedAggFunc(AnonymousAggFunc):
4629    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4632class CombinedParameterizedAgg(ParameterizedAgg):
4633    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):
4638class Hll(AggFunc):
4639    arg_types = {"this": True, "expressions": False}
4640    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4643class ApproxDistinct(AggFunc):
4644    arg_types = {"this": True, "accuracy": False}
4645    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4648class Array(Func):
4649    arg_types = {"expressions": False}
4650    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4654class ToArray(Func):
4655    pass
key = 'toarray'
class ToChar(Func):
4660class ToChar(Func):
4661    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4666class ToNumber(Func):
4667    arg_types = {
4668        "this": True,
4669        "format": False,
4670        "nlsparam": False,
4671        "precision": False,
4672        "scale": False,
4673    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4677class Convert(Func):
4678    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4681class GenerateSeries(Func):
4682    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):
4685class ArrayAgg(AggFunc):
4686    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4689class ArrayUniqueAgg(AggFunc):
4690    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4693class ArrayAll(Func):
4694    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4698class ArrayAny(Func):
4699    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4702class ArrayConcat(Func):
4703    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4704    arg_types = {"this": True, "expressions": False}
4705    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4708class ArrayContains(Binary, Func):
4709    pass
key = 'arraycontains'
class ArrayContained(Binary):
4712class ArrayContained(Binary):
4713    pass
key = 'arraycontained'
class ArrayFilter(Func):
4716class ArrayFilter(Func):
4717    arg_types = {"this": True, "expression": True}
4718    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4721class ArrayToString(Func):
4722    arg_types = {"this": True, "expression": True, "null": False}
4723    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4726class ArrayOverlaps(Binary, Func):
4727    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4730class ArraySize(Func):
4731    arg_types = {"this": True, "expression": False}
4732    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4735class ArraySort(Func):
4736    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4739class ArraySum(Func):
4740    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4743class ArrayUnionAgg(AggFunc):
4744    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4747class Avg(AggFunc):
4748    pass
key = 'avg'
class AnyValue(AggFunc):
4751class AnyValue(AggFunc):
4752    pass
key = 'anyvalue'
class Lag(AggFunc):
4755class Lag(AggFunc):
4756    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4759class Lead(AggFunc):
4760    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4765class First(AggFunc):
4766    pass
key = 'first'
class Last(AggFunc):
4769class Last(AggFunc):
4770    pass
key = 'last'
class FirstValue(AggFunc):
4773class FirstValue(AggFunc):
4774    pass
key = 'firstvalue'
class LastValue(AggFunc):
4777class LastValue(AggFunc):
4778    pass
key = 'lastvalue'
class NthValue(AggFunc):
4781class NthValue(AggFunc):
4782    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4785class Case(Func):
4786    arg_types = {"this": False, "ifs": True, "default": False}
4787
4788    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4789        instance = maybe_copy(self, copy)
4790        instance.append(
4791            "ifs",
4792            If(
4793                this=maybe_parse(condition, copy=copy, **opts),
4794                true=maybe_parse(then, copy=copy, **opts),
4795            ),
4796        )
4797        return instance
4798
4799    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4800        instance = maybe_copy(self, copy)
4801        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4802        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:
4788    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4789        instance = maybe_copy(self, copy)
4790        instance.append(
4791            "ifs",
4792            If(
4793                this=maybe_parse(condition, copy=copy, **opts),
4794                true=maybe_parse(then, copy=copy, **opts),
4795            ),
4796        )
4797        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4799    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4800        instance = maybe_copy(self, copy)
4801        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4802        return instance
key = 'case'
class Cast(Func):
4805class Cast(Func):
4806    arg_types = {
4807        "this": True,
4808        "to": True,
4809        "format": False,
4810        "safe": False,
4811        "action": False,
4812    }
4813
4814    @property
4815    def name(self) -> str:
4816        return self.this.name
4817
4818    @property
4819    def to(self) -> DataType:
4820        return self.args["to"]
4821
4822    @property
4823    def output_name(self) -> str:
4824        return self.name
4825
4826    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4827        """
4828        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4829        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4830        array<int> != array<float>.
4831
4832        Args:
4833            dtypes: the data types to compare this Cast's DataType to.
4834
4835        Returns:
4836            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4837        """
4838        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4814    @property
4815    def name(self) -> str:
4816        return self.this.name
to: DataType
4818    @property
4819    def to(self) -> DataType:
4820        return self.args["to"]
output_name: str
4822    @property
4823    def output_name(self) -> str:
4824        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:
4826    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4827        """
4828        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4829        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4830        array<int> != array<float>.
4831
4832        Args:
4833            dtypes: the data types to compare this Cast's DataType to.
4834
4835        Returns:
4836            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4837        """
4838        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):
4841class TryCast(Cast):
4842    pass
key = 'trycast'
class CastToStrType(Func):
4845class CastToStrType(Func):
4846    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4849class Collate(Binary, Func):
4850    pass
key = 'collate'
class Ceil(Func):
4853class Ceil(Func):
4854    arg_types = {"this": True, "decimals": False}
4855    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4858class Coalesce(Func):
4859    arg_types = {"this": True, "expressions": False}
4860    is_var_len_args = True
4861    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4864class Chr(Func):
4865    arg_types = {"this": True, "charset": False, "expressions": False}
4866    is_var_len_args = True
4867    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4870class Concat(Func):
4871    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4872    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4875class ConcatWs(Concat):
4876    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4880class ConnectByRoot(Func):
4881    pass
key = 'connectbyroot'
class Count(AggFunc):
4884class Count(AggFunc):
4885    arg_types = {"this": False, "expressions": False}
4886    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4889class CountIf(AggFunc):
4890    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4894class Cbrt(Func):
4895    pass
key = 'cbrt'
class CurrentDate(Func):
4898class CurrentDate(Func):
4899    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4902class CurrentDatetime(Func):
4903    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4906class CurrentTime(Func):
4907    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4910class CurrentTimestamp(Func):
4911    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4914class CurrentUser(Func):
4915    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4918class DateAdd(Func, IntervalOp):
4919    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4922class DateSub(Func, IntervalOp):
4923    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4926class DateDiff(Func, TimeUnit):
4927    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4928    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4931class DateTrunc(Func):
4932    arg_types = {"unit": True, "this": True, "zone": False}
4933
4934    def __init__(self, **args):
4935        unit = args.get("unit")
4936        if isinstance(unit, TimeUnit.VAR_LIKE):
4937            args["unit"] = Literal.string(
4938                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4939            )
4940        elif isinstance(unit, Week):
4941            unit.set("this", Literal.string(unit.this.name.upper()))
4942
4943        super().__init__(**args)
4944
4945    @property
4946    def unit(self) -> Expression:
4947        return self.args["unit"]
DateTrunc(**args)
4934    def __init__(self, **args):
4935        unit = args.get("unit")
4936        if isinstance(unit, TimeUnit.VAR_LIKE):
4937            args["unit"] = Literal.string(
4938                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4939            )
4940        elif isinstance(unit, Week):
4941            unit.set("this", Literal.string(unit.this.name.upper()))
4942
4943        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4945    @property
4946    def unit(self) -> Expression:
4947        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4950class DatetimeAdd(Func, IntervalOp):
4951    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4954class DatetimeSub(Func, IntervalOp):
4955    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4958class DatetimeDiff(Func, TimeUnit):
4959    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4962class DatetimeTrunc(Func, TimeUnit):
4963    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4966class DayOfWeek(Func):
4967    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4970class DayOfMonth(Func):
4971    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4974class DayOfYear(Func):
4975    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4978class ToDays(Func):
4979    pass
key = 'todays'
class WeekOfYear(Func):
4982class WeekOfYear(Func):
4983    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4986class MonthsBetween(Func):
4987    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4990class LastDay(Func, TimeUnit):
4991    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4992    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4995class Extract(Func):
4996    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4999class Timestamp(Func):
5000    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5003class TimestampAdd(Func, TimeUnit):
5004    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5007class TimestampSub(Func, TimeUnit):
5008    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5011class TimestampDiff(Func, TimeUnit):
5012    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5013    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5016class TimestampTrunc(Func, TimeUnit):
5017    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5020class TimeAdd(Func, TimeUnit):
5021    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5024class TimeSub(Func, TimeUnit):
5025    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5028class TimeDiff(Func, TimeUnit):
5029    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5032class TimeTrunc(Func, TimeUnit):
5033    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5036class DateFromParts(Func):
5037    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5038    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5041class TimeFromParts(Func):
5042    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5043    arg_types = {
5044        "hour": True,
5045        "min": True,
5046        "sec": True,
5047        "nano": False,
5048        "fractions": False,
5049        "precision": False,
5050    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5053class DateStrToDate(Func):
5054    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5057class DateToDateStr(Func):
5058    pass
key = 'datetodatestr'
class DateToDi(Func):
5061class DateToDi(Func):
5062    pass
key = 'datetodi'
class Date(Func):
5066class Date(Func):
5067    arg_types = {"this": False, "zone": False, "expressions": False}
5068    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5071class Day(Func):
5072    pass
key = 'day'
class Decode(Func):
5075class Decode(Func):
5076    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5079class DiToDate(Func):
5080    pass
key = 'ditodate'
class Encode(Func):
5083class Encode(Func):
5084    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5087class Exp(Func):
5088    pass
key = 'exp'
class Explode(Func):
5092class Explode(Func):
5093    arg_types = {"this": True, "expressions": False}
5094    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5097class ExplodeOuter(Explode):
5098    pass
key = 'explodeouter'
class Posexplode(Explode):
5101class Posexplode(Explode):
5102    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5105class PosexplodeOuter(Posexplode, ExplodeOuter):
5106    pass
key = 'posexplodeouter'
class Floor(Func):
5109class Floor(Func):
5110    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5113class FromBase64(Func):
5114    pass
key = 'frombase64'
class ToBase64(Func):
5117class ToBase64(Func):
5118    pass
key = 'tobase64'
class GenerateDateArray(Func):
5121class GenerateDateArray(Func):
5122    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5125class Greatest(Func):
5126    arg_types = {"this": True, "expressions": False}
5127    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5130class GroupConcat(AggFunc):
5131    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5134class Hex(Func):
5135    pass
key = 'hex'
class Xor(Connector, Func):
5138class Xor(Connector, Func):
5139    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5142class If(Func):
5143    arg_types = {"this": True, "true": True, "false": False}
5144    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5147class Nullif(Func):
5148    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5151class Initcap(Func):
5152    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5155class IsNan(Func):
5156    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5159class IsInf(Func):
5160    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5163class JSONPath(Expression):
5164    arg_types = {"expressions": True}
5165
5166    @property
5167    def output_name(self) -> str:
5168        last_segment = self.expressions[-1].this
5169        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5166    @property
5167    def output_name(self) -> str:
5168        last_segment = self.expressions[-1].this
5169        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):
5172class JSONPathPart(Expression):
5173    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5176class JSONPathFilter(JSONPathPart):
5177    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5180class JSONPathKey(JSONPathPart):
5181    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5184class JSONPathRecursive(JSONPathPart):
5185    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5188class JSONPathRoot(JSONPathPart):
5189    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5192class JSONPathScript(JSONPathPart):
5193    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5196class JSONPathSlice(JSONPathPart):
5197    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5200class JSONPathSelector(JSONPathPart):
5201    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5204class JSONPathSubscript(JSONPathPart):
5205    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5208class JSONPathUnion(JSONPathPart):
5209    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5212class JSONPathWildcard(JSONPathPart):
5213    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5216class FormatJson(Expression):
5217    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5220class JSONKeyValue(Expression):
5221    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5224class JSONObject(Func):
5225    arg_types = {
5226        "expressions": False,
5227        "null_handling": False,
5228        "unique_keys": False,
5229        "return_type": False,
5230        "encoding": False,
5231    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5234class JSONObjectAgg(AggFunc):
5235    arg_types = {
5236        "expressions": False,
5237        "null_handling": False,
5238        "unique_keys": False,
5239        "return_type": False,
5240        "encoding": False,
5241    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5245class JSONArray(Func):
5246    arg_types = {
5247        "expressions": True,
5248        "null_handling": False,
5249        "return_type": False,
5250        "strict": False,
5251    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5255class JSONArrayAgg(Func):
5256    arg_types = {
5257        "this": True,
5258        "order": False,
5259        "null_handling": False,
5260        "return_type": False,
5261        "strict": False,
5262    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5267class JSONColumnDef(Expression):
5268    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):
5271class JSONSchema(Expression):
5272    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5276class JSONTable(Func):
5277    arg_types = {
5278        "this": True,
5279        "schema": True,
5280        "path": False,
5281        "error_handling": False,
5282        "empty_handling": False,
5283    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5286class OpenJSONColumnDef(Expression):
5287    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):
5290class OpenJSON(Func):
5291    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5294class JSONBContains(Binary):
5295    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5298class JSONExtract(Binary, Func):
5299    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5300    _sql_names = ["JSON_EXTRACT"]
5301    is_var_len_args = True
5302
5303    @property
5304    def output_name(self) -> str:
5305        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
5303    @property
5304    def output_name(self) -> str:
5305        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):
5308class JSONExtractScalar(Binary, Func):
5309    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5310    _sql_names = ["JSON_EXTRACT_SCALAR"]
5311    is_var_len_args = True
5312
5313    @property
5314    def output_name(self) -> str:
5315        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
5313    @property
5314    def output_name(self) -> str:
5315        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):
5318class JSONBExtract(Binary, Func):
5319    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5322class JSONBExtractScalar(Binary, Func):
5323    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5326class JSONFormat(Func):
5327    arg_types = {"this": False, "options": False}
5328    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5332class JSONArrayContains(Binary, Predicate, Func):
5333    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5336class ParseJSON(Func):
5337    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5338    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5339    arg_types = {"this": True, "expressions": False}
5340    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5343class Least(Func):
5344    arg_types = {"this": True, "expressions": False}
5345    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5348class Left(Func):
5349    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5356class Length(Func):
5357    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5360class Levenshtein(Func):
5361    arg_types = {
5362        "this": True,
5363        "expression": False,
5364        "ins_cost": False,
5365        "del_cost": False,
5366        "sub_cost": False,
5367    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5370class Ln(Func):
5371    pass
key = 'ln'
class Log(Func):
5374class Log(Func):
5375    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5378class LogicalOr(AggFunc):
5379    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5382class LogicalAnd(AggFunc):
5383    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5386class Lower(Func):
5387    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5390class Map(Func):
5391    arg_types = {"keys": False, "values": False}
5392
5393    @property
5394    def keys(self) -> t.List[Expression]:
5395        keys = self.args.get("keys")
5396        return keys.expressions if keys else []
5397
5398    @property
5399    def values(self) -> t.List[Expression]:
5400        values = self.args.get("values")
5401        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5393    @property
5394    def keys(self) -> t.List[Expression]:
5395        keys = self.args.get("keys")
5396        return keys.expressions if keys else []
values: List[Expression]
5398    @property
5399    def values(self) -> t.List[Expression]:
5400        values = self.args.get("values")
5401        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5405class ToMap(Func):
5406    pass
key = 'tomap'
class MapFromEntries(Func):
5409class MapFromEntries(Func):
5410    pass
key = 'mapfromentries'
class StarMap(Func):
5413class StarMap(Func):
5414    pass
key = 'starmap'
class VarMap(Func):
5417class VarMap(Func):
5418    arg_types = {"keys": True, "values": True}
5419    is_var_len_args = True
5420
5421    @property
5422    def keys(self) -> t.List[Expression]:
5423        return self.args["keys"].expressions
5424
5425    @property
5426    def values(self) -> t.List[Expression]:
5427        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5421    @property
5422    def keys(self) -> t.List[Expression]:
5423        return self.args["keys"].expressions
values: List[Expression]
5425    @property
5426    def values(self) -> t.List[Expression]:
5427        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5431class MatchAgainst(Func):
5432    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5435class Max(AggFunc):
5436    arg_types = {"this": True, "expressions": False}
5437    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5440class MD5(Func):
5441    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5445class MD5Digest(Func):
5446    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5449class Min(AggFunc):
5450    arg_types = {"this": True, "expressions": False}
5451    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5454class Month(Func):
5455    pass
key = 'month'
class AddMonths(Func):
5458class AddMonths(Func):
5459    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5462class Nvl2(Func):
5463    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5467class Predict(Func):
5468    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5471class Pow(Binary, Func):
5472    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5475class PercentileCont(AggFunc):
5476    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5479class PercentileDisc(AggFunc):
5480    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5483class Quantile(AggFunc):
5484    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5487class ApproxQuantile(Quantile):
5488    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
5491class Quarter(Func):
5492    pass
key = 'quarter'
class Rand(Func):
5495class Rand(Func):
5496    _sql_names = ["RAND", "RANDOM"]
5497    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5500class Randn(Func):
5501    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5504class RangeN(Func):
5505    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5508class ReadCSV(Func):
5509    _sql_names = ["READ_CSV"]
5510    is_var_len_args = True
5511    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5514class Reduce(Func):
5515    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):
5518class RegexpExtract(Func):
5519    arg_types = {
5520        "this": True,
5521        "expression": True,
5522        "position": False,
5523        "occurrence": False,
5524        "parameters": False,
5525        "group": False,
5526    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5529class RegexpReplace(Func):
5530    arg_types = {
5531        "this": True,
5532        "expression": True,
5533        "replacement": False,
5534        "position": False,
5535        "occurrence": False,
5536        "parameters": False,
5537        "modifiers": False,
5538    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5541class RegexpLike(Binary, Func):
5542    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5545class RegexpILike(Binary, Func):
5546    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5551class RegexpSplit(Func):
5552    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5555class Repeat(Func):
5556    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5561class Round(Func):
5562    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5565class RowNumber(Func):
5566    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5569class SafeDivide(Func):
5570    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5573class SHA(Func):
5574    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5577class SHA2(Func):
5578    _sql_names = ["SHA2"]
5579    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5582class Sign(Func):
5583    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5586class SortArray(Func):
5587    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5590class Split(Func):
5591    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5596class Substring(Func):
5597    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5600class StandardHash(Func):
5601    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5604class StartsWith(Func):
5605    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5606    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5609class StrPosition(Func):
5610    arg_types = {
5611        "this": True,
5612        "substr": True,
5613        "position": False,
5614        "instance": False,
5615    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5618class StrToDate(Func):
5619    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5622class StrToTime(Func):
5623    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5628class StrToUnix(Func):
5629    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5634class StrToMap(Func):
5635    arg_types = {
5636        "this": True,
5637        "pair_delim": False,
5638        "key_value_delim": False,
5639        "duplicate_resolution_callback": False,
5640    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5643class NumberToStr(Func):
5644    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5647class FromBase(Func):
5648    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5651class Struct(Func):
5652    arg_types = {"expressions": False}
5653    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5656class StructExtract(Func):
5657    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5662class Stuff(Func):
5663    _sql_names = ["STUFF", "INSERT"]
5664    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):
5667class Sum(AggFunc):
5668    pass
key = 'sum'
class Sqrt(Func):
5671class Sqrt(Func):
5672    pass
key = 'sqrt'
class Stddev(AggFunc):
5675class Stddev(AggFunc):
5676    pass
key = 'stddev'
class StddevPop(AggFunc):
5679class StddevPop(AggFunc):
5680    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5683class StddevSamp(AggFunc):
5684    pass
key = 'stddevsamp'
class TimeToStr(Func):
5687class TimeToStr(Func):
5688    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'timezone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5691class TimeToTimeStr(Func):
5692    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5695class TimeToUnix(Func):
5696    pass
key = 'timetounix'
class TimeStrToDate(Func):
5699class TimeStrToDate(Func):
5700    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5703class TimeStrToTime(Func):
5704    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5707class TimeStrToUnix(Func):
5708    pass
key = 'timestrtounix'
class Trim(Func):
5711class Trim(Func):
5712    arg_types = {
5713        "this": True,
5714        "expression": False,
5715        "position": False,
5716        "collation": False,
5717    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5720class TsOrDsAdd(Func, TimeUnit):
5721    # return_type is used to correctly cast the arguments of this expression when transpiling it
5722    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5723
5724    @property
5725    def return_type(self) -> DataType:
5726        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
5724    @property
5725    def return_type(self) -> DataType:
5726        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5729class TsOrDsDiff(Func, TimeUnit):
5730    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5733class TsOrDsToDateStr(Func):
5734    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5737class TsOrDsToDate(Func):
5738    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5741class TsOrDsToTime(Func):
5742    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5745class TsOrDsToTimestamp(Func):
5746    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5749class TsOrDiToDi(Func):
5750    pass
key = 'tsorditodi'
class Unhex(Func):
5753class Unhex(Func):
5754    pass
key = 'unhex'
class UnixDate(Func):
5758class UnixDate(Func):
5759    pass
key = 'unixdate'
class UnixToStr(Func):
5762class UnixToStr(Func):
5763    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5768class UnixToTime(Func):
5769    arg_types = {
5770        "this": True,
5771        "scale": False,
5772        "zone": False,
5773        "hours": False,
5774        "minutes": False,
5775        "format": False,
5776    }
5777
5778    SECONDS = Literal.number(0)
5779    DECIS = Literal.number(1)
5780    CENTIS = Literal.number(2)
5781    MILLIS = Literal.number(3)
5782    DECIMILLIS = Literal.number(4)
5783    CENTIMILLIS = Literal.number(5)
5784    MICROS = Literal.number(6)
5785    DECIMICROS = Literal.number(7)
5786    CENTIMICROS = Literal.number(8)
5787    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': 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):
5790class UnixToTimeStr(Func):
5791    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5794class TimestampFromParts(Func):
5795    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5796    arg_types = {
5797        "year": True,
5798        "month": True,
5799        "day": True,
5800        "hour": True,
5801        "min": True,
5802        "sec": True,
5803        "nano": False,
5804        "zone": False,
5805        "milli": False,
5806    }
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):
5809class Upper(Func):
5810    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5813class Corr(Binary, AggFunc):
5814    pass
key = 'corr'
class Variance(AggFunc):
5817class Variance(AggFunc):
5818    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5821class VariancePop(AggFunc):
5822    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5825class CovarSamp(Binary, AggFunc):
5826    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5829class CovarPop(Binary, AggFunc):
5830    pass
key = 'covarpop'
class Week(Func):
5833class Week(Func):
5834    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5837class XMLTable(Func):
5838    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):
5841class Year(Func):
5842    pass
key = 'year'
class Use(Expression):
5845class Use(Expression):
5846    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5849class Merge(Expression):
5850    arg_types = {
5851        "this": True,
5852        "using": True,
5853        "on": True,
5854        "expressions": True,
5855        "with": False,
5856    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5859class When(Func):
5860    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):
5865class NextValueFor(Func):
5866    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <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 'GenerateDateArray'>, <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 '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 'Quarter'>, <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 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, '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_DATE_ARRAY': <class 'GenerateDateArray'>, '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'>, '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'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, '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:
5904def maybe_parse(
5905    sql_or_expression: ExpOrStr,
5906    *,
5907    into: t.Optional[IntoType] = None,
5908    dialect: DialectType = None,
5909    prefix: t.Optional[str] = None,
5910    copy: bool = False,
5911    **opts,
5912) -> Expression:
5913    """Gracefully handle a possible string or expression.
5914
5915    Example:
5916        >>> maybe_parse("1")
5917        Literal(this=1, is_string=False)
5918        >>> maybe_parse(to_identifier("x"))
5919        Identifier(this=x, quoted=False)
5920
5921    Args:
5922        sql_or_expression: the SQL code string or an expression
5923        into: the SQLGlot Expression to parse into
5924        dialect: the dialect used to parse the input expressions (in the case that an
5925            input expression is a SQL string).
5926        prefix: a string to prefix the sql with before it gets parsed
5927            (automatically includes a space)
5928        copy: whether to copy the expression.
5929        **opts: other options to use to parse the input expressions (again, in the case
5930            that an input expression is a SQL string).
5931
5932    Returns:
5933        Expression: the parsed or given expression.
5934    """
5935    if isinstance(sql_or_expression, Expression):
5936        if copy:
5937            return sql_or_expression.copy()
5938        return sql_or_expression
5939
5940    if sql_or_expression is None:
5941        raise ParseError("SQL cannot be None")
5942
5943    import sqlglot
5944
5945    sql = str(sql_or_expression)
5946    if prefix:
5947        sql = f"{prefix} {sql}"
5948
5949    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):
5960def maybe_copy(instance, copy=True):
5961    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:
6175def union(
6176    left: ExpOrStr,
6177    right: ExpOrStr,
6178    distinct: bool = True,
6179    dialect: DialectType = None,
6180    copy: bool = True,
6181    **opts,
6182) -> Union:
6183    """
6184    Initializes a syntax tree from one UNION expression.
6185
6186    Example:
6187        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6188        'SELECT * FROM foo UNION SELECT * FROM bla'
6189
6190    Args:
6191        left: the SQL code string corresponding to the left-hand side.
6192            If an `Expression` instance is passed, it will be used as-is.
6193        right: the SQL code string corresponding to the right-hand side.
6194            If an `Expression` instance is passed, it will be used as-is.
6195        distinct: set the DISTINCT flag if and only if this is true.
6196        dialect: the dialect used to parse the input expression.
6197        copy: whether to copy the expression.
6198        opts: other options to use to parse the input expressions.
6199
6200    Returns:
6201        The new Union instance.
6202    """
6203    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6204    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6205
6206    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:
6209def intersect(
6210    left: ExpOrStr,
6211    right: ExpOrStr,
6212    distinct: bool = True,
6213    dialect: DialectType = None,
6214    copy: bool = True,
6215    **opts,
6216) -> Intersect:
6217    """
6218    Initializes a syntax tree from one INTERSECT expression.
6219
6220    Example:
6221        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6222        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6223
6224    Args:
6225        left: the SQL code string corresponding to the left-hand side.
6226            If an `Expression` instance is passed, it will be used as-is.
6227        right: the SQL code string corresponding to the right-hand side.
6228            If an `Expression` instance is passed, it will be used as-is.
6229        distinct: set the DISTINCT flag if and only if this is true.
6230        dialect: the dialect used to parse the input expression.
6231        copy: whether to copy the expression.
6232        opts: other options to use to parse the input expressions.
6233
6234    Returns:
6235        The new Intersect instance.
6236    """
6237    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6238    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6239
6240    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:
6243def except_(
6244    left: ExpOrStr,
6245    right: ExpOrStr,
6246    distinct: bool = True,
6247    dialect: DialectType = None,
6248    copy: bool = True,
6249    **opts,
6250) -> Except:
6251    """
6252    Initializes a syntax tree from one EXCEPT expression.
6253
6254    Example:
6255        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6256        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6257
6258    Args:
6259        left: the SQL code string corresponding to the left-hand side.
6260            If an `Expression` instance is passed, it will be used as-is.
6261        right: the SQL code string corresponding to the right-hand side.
6262            If an `Expression` instance is passed, it will be used as-is.
6263        distinct: set the DISTINCT flag if and only if this is true.
6264        dialect: the dialect used to parse the input expression.
6265        copy: whether to copy the expression.
6266        opts: other options to use to parse the input expressions.
6267
6268    Returns:
6269        The new Except instance.
6270    """
6271    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6272    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6273
6274    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:
6277def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6278    """
6279    Initializes a syntax tree from one or multiple SELECT expressions.
6280
6281    Example:
6282        >>> select("col1", "col2").from_("tbl").sql()
6283        'SELECT col1, col2 FROM tbl'
6284
6285    Args:
6286        *expressions: the SQL code string to parse as the expressions of a
6287            SELECT statement. If an Expression instance is passed, this is used as-is.
6288        dialect: the dialect used to parse the input expressions (in the case that an
6289            input expression is a SQL string).
6290        **opts: other options to use to parse the input expressions (again, in the case
6291            that an input expression is a SQL string).
6292
6293    Returns:
6294        Select: the syntax tree for the SELECT statement.
6295    """
6296    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:
6299def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6300    """
6301    Initializes a syntax tree from a FROM expression.
6302
6303    Example:
6304        >>> from_("tbl").select("col1", "col2").sql()
6305        'SELECT col1, col2 FROM tbl'
6306
6307    Args:
6308        *expression: the SQL code string to parse as the FROM expressions of a
6309            SELECT statement. If an Expression instance is passed, this is used as-is.
6310        dialect: the dialect used to parse the input expression (in the case that the
6311            input expression is a SQL string).
6312        **opts: other options to use to parse the input expressions (again, in the case
6313            that the input expression is a SQL string).
6314
6315    Returns:
6316        Select: the syntax tree for the SELECT statement.
6317    """
6318    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:
6321def update(
6322    table: str | Table,
6323    properties: dict,
6324    where: t.Optional[ExpOrStr] = None,
6325    from_: t.Optional[ExpOrStr] = None,
6326    dialect: DialectType = None,
6327    **opts,
6328) -> Update:
6329    """
6330    Creates an update statement.
6331
6332    Example:
6333        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6334        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6335
6336    Args:
6337        *properties: dictionary of properties to set which are
6338            auto converted to sql objects eg None -> NULL
6339        where: sql conditional parsed into a WHERE statement
6340        from_: sql statement parsed into a FROM statement
6341        dialect: the dialect used to parse the input expressions.
6342        **opts: other options to use to parse the input expressions.
6343
6344    Returns:
6345        Update: the syntax tree for the UPDATE statement.
6346    """
6347    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6348    update_expr.set(
6349        "expressions",
6350        [
6351            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6352            for k, v in properties.items()
6353        ],
6354    )
6355    if from_:
6356        update_expr.set(
6357            "from",
6358            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6359        )
6360    if isinstance(where, Condition):
6361        where = Where(this=where)
6362    if where:
6363        update_expr.set(
6364            "where",
6365            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6366        )
6367    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:
6370def delete(
6371    table: ExpOrStr,
6372    where: t.Optional[ExpOrStr] = None,
6373    returning: t.Optional[ExpOrStr] = None,
6374    dialect: DialectType = None,
6375    **opts,
6376) -> Delete:
6377    """
6378    Builds a delete statement.
6379
6380    Example:
6381        >>> delete("my_table", where="id > 1").sql()
6382        'DELETE FROM my_table WHERE id > 1'
6383
6384    Args:
6385        where: sql conditional parsed into a WHERE statement
6386        returning: sql conditional parsed into a RETURNING statement
6387        dialect: the dialect used to parse the input expressions.
6388        **opts: other options to use to parse the input expressions.
6389
6390    Returns:
6391        Delete: the syntax tree for the DELETE statement.
6392    """
6393    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6394    if where:
6395        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6396    if returning:
6397        delete_expr = t.cast(
6398            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6399        )
6400    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:
6403def insert(
6404    expression: ExpOrStr,
6405    into: ExpOrStr,
6406    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6407    overwrite: t.Optional[bool] = None,
6408    returning: t.Optional[ExpOrStr] = None,
6409    dialect: DialectType = None,
6410    copy: bool = True,
6411    **opts,
6412) -> Insert:
6413    """
6414    Builds an INSERT statement.
6415
6416    Example:
6417        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6418        'INSERT INTO tbl VALUES (1, 2, 3)'
6419
6420    Args:
6421        expression: the sql string or expression of the INSERT statement
6422        into: the tbl to insert data to.
6423        columns: optionally the table's column names.
6424        overwrite: whether to INSERT OVERWRITE or not.
6425        returning: sql conditional parsed into a RETURNING statement
6426        dialect: the dialect used to parse the input expressions.
6427        copy: whether to copy the expression.
6428        **opts: other options to use to parse the input expressions.
6429
6430    Returns:
6431        Insert: the syntax tree for the INSERT statement.
6432    """
6433    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6434    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6435
6436    if columns:
6437        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6438
6439    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6440
6441    if returning:
6442        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6443
6444    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:
6447def condition(
6448    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6449) -> Condition:
6450    """
6451    Initialize a logical condition expression.
6452
6453    Example:
6454        >>> condition("x=1").sql()
6455        'x = 1'
6456
6457        This is helpful for composing larger logical syntax trees:
6458        >>> where = condition("x=1")
6459        >>> where = where.and_("y=1")
6460        >>> Select().from_("tbl").select("*").where(where).sql()
6461        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6462
6463    Args:
6464        *expression: the SQL code string to parse.
6465            If an Expression instance is passed, this is used as-is.
6466        dialect: the dialect used to parse the input expression (in the case that the
6467            input expression is a SQL string).
6468        copy: Whether to copy `expression` (only applies to expressions).
6469        **opts: other options to use to parse the input expressions (again, in the case
6470            that the input expression is a SQL string).
6471
6472    Returns:
6473        The new Condition instance
6474    """
6475    return maybe_parse(
6476        expression,
6477        into=Condition,
6478        dialect=dialect,
6479        copy=copy,
6480        **opts,
6481    )

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:
6484def and_(
6485    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6486) -> Condition:
6487    """
6488    Combine multiple conditions with an AND logical operator.
6489
6490    Example:
6491        >>> and_("x=1", and_("y=1", "z=1")).sql()
6492        'x = 1 AND (y = 1 AND z = 1)'
6493
6494    Args:
6495        *expressions: the SQL code strings to parse.
6496            If an Expression instance is passed, this is used as-is.
6497        dialect: the dialect used to parse the input expression.
6498        copy: whether to copy `expressions` (only applies to Expressions).
6499        **opts: other options to use to parse the input expressions.
6500
6501    Returns:
6502        And: the new condition
6503    """
6504    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:
6507def or_(
6508    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6509) -> Condition:
6510    """
6511    Combine multiple conditions with an OR logical operator.
6512
6513    Example:
6514        >>> or_("x=1", or_("y=1", "z=1")).sql()
6515        'x = 1 OR (y = 1 OR z = 1)'
6516
6517    Args:
6518        *expressions: the SQL code strings to parse.
6519            If an Expression instance is passed, this is used as-is.
6520        dialect: the dialect used to parse the input expression.
6521        copy: whether to copy `expressions` (only applies to Expressions).
6522        **opts: other options to use to parse the input expressions.
6523
6524    Returns:
6525        Or: the new condition
6526    """
6527    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:
6530def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6531    """
6532    Wrap a condition with a NOT operator.
6533
6534    Example:
6535        >>> not_("this_suit='black'").sql()
6536        "NOT this_suit = 'black'"
6537
6538    Args:
6539        expression: the SQL code string to parse.
6540            If an Expression instance is passed, this is used as-is.
6541        dialect: the dialect used to parse the input expression.
6542        copy: whether to copy the expression or not.
6543        **opts: other options to use to parse the input expressions.
6544
6545    Returns:
6546        The new condition.
6547    """
6548    this = condition(
6549        expression,
6550        dialect=dialect,
6551        copy=copy,
6552        **opts,
6553    )
6554    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:
6557def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6558    """
6559    Wrap an expression in parentheses.
6560
6561    Example:
6562        >>> paren("5 + 3").sql()
6563        '(5 + 3)'
6564
6565    Args:
6566        expression: the SQL code string to parse.
6567            If an Expression instance is passed, this is used as-is.
6568        copy: whether to copy the expression or not.
6569
6570    Returns:
6571        The wrapped expression.
6572    """
6573    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):
6589def to_identifier(name, quoted=None, copy=True):
6590    """Builds an identifier.
6591
6592    Args:
6593        name: The name to turn into an identifier.
6594        quoted: Whether to force quote the identifier.
6595        copy: Whether to copy name if it's an Identifier.
6596
6597    Returns:
6598        The identifier ast node.
6599    """
6600
6601    if name is None:
6602        return None
6603
6604    if isinstance(name, Identifier):
6605        identifier = maybe_copy(name, copy)
6606    elif isinstance(name, str):
6607        identifier = Identifier(
6608            this=name,
6609            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6610        )
6611    else:
6612        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6613    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:
6616def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6617    """
6618    Parses a given string into an identifier.
6619
6620    Args:
6621        name: The name to parse into an identifier.
6622        dialect: The dialect to parse against.
6623
6624    Returns:
6625        The identifier ast node.
6626    """
6627    try:
6628        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6629    except ParseError:
6630        expression = to_identifier(name)
6631
6632    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:
6638def to_interval(interval: str | Literal) -> Interval:
6639    """Builds an interval expression from a string like '1 day' or '5 months'."""
6640    if isinstance(interval, Literal):
6641        if not interval.is_string:
6642            raise ValueError("Invalid interval string.")
6643
6644        interval = interval.this
6645
6646    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6647
6648    if not interval_parts:
6649        raise ValueError("Invalid interval string.")
6650
6651    return Interval(
6652        this=Literal.string(interval_parts.group(1)),
6653        unit=Var(this=interval_parts.group(2).upper()),
6654    )

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
6657def to_table(
6658    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6659) -> Table:
6660    """
6661    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6662    If a table is passed in then that table is returned.
6663
6664    Args:
6665        sql_path: a `[catalog].[schema].[table]` string.
6666        dialect: the source dialect according to which the table name will be parsed.
6667        copy: Whether to copy a table if it is passed in.
6668        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6669
6670    Returns:
6671        A table expression.
6672    """
6673    if isinstance(sql_path, Table):
6674        return maybe_copy(sql_path, copy=copy)
6675
6676    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6677
6678    for k, v in kwargs.items():
6679        table.set(k, v)
6680
6681    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, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6684def to_column(
6685    sql_path: str | Column,
6686    quoted: t.Optional[bool] = None,
6687    dialect: DialectType = None,
6688    copy: bool = True,
6689    **kwargs,
6690) -> Column:
6691    """
6692    Create a column from a `[table].[column]` sql path. Table is optional.
6693    If a column is passed in then that column is returned.
6694
6695    Args:
6696        sql_path: a `[table].[column]` string.
6697        quoted: Whether or not to force quote identifiers.
6698        dialect: the source dialect according to which the column name will be parsed.
6699        copy: Whether to copy a column if it is passed in.
6700        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6701
6702    Returns:
6703        A column expression.
6704    """
6705    if isinstance(sql_path, Column):
6706        return maybe_copy(sql_path, copy=copy)
6707
6708    try:
6709        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6710    except ParseError:
6711        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6712
6713    for k, v in kwargs.items():
6714        col.set(k, v)
6715
6716    if quoted:
6717        for i in col.find_all(Identifier):
6718            i.set("quoted", True)
6719
6720    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

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):
6723def alias_(
6724    expression: ExpOrStr,
6725    alias: t.Optional[str | Identifier],
6726    table: bool | t.Sequence[str | Identifier] = False,
6727    quoted: t.Optional[bool] = None,
6728    dialect: DialectType = None,
6729    copy: bool = True,
6730    **opts,
6731):
6732    """Create an Alias expression.
6733
6734    Example:
6735        >>> alias_('foo', 'bar').sql()
6736        'foo AS bar'
6737
6738        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6739        '(SELECT 1, 2) AS bar(a, b)'
6740
6741    Args:
6742        expression: the SQL code strings to parse.
6743            If an Expression instance is passed, this is used as-is.
6744        alias: the alias name to use. If the name has
6745            special characters it is quoted.
6746        table: Whether to create a table alias, can also be a list of columns.
6747        quoted: whether to quote the alias
6748        dialect: the dialect used to parse the input expression.
6749        copy: Whether to copy the expression.
6750        **opts: other options to use to parse the input expressions.
6751
6752    Returns:
6753        Alias: the aliased expression
6754    """
6755    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6756    alias = to_identifier(alias, quoted=quoted)
6757
6758    if table:
6759        table_alias = TableAlias(this=alias)
6760        exp.set("alias", table_alias)
6761
6762        if not isinstance(table, bool):
6763            for column in table:
6764                table_alias.append("columns", to_identifier(column, quoted=quoted))
6765
6766        return exp
6767
6768    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6769    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6770    # for the complete Window expression.
6771    #
6772    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6773
6774    if "alias" in exp.arg_types and not isinstance(exp, Window):
6775        exp.set("alias", alias)
6776        return exp
6777    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:
6780def subquery(
6781    expression: ExpOrStr,
6782    alias: t.Optional[Identifier | str] = None,
6783    dialect: DialectType = None,
6784    **opts,
6785) -> Select:
6786    """
6787    Build a subquery expression that's selected from.
6788
6789    Example:
6790        >>> subquery('select x from tbl', 'bar').select('x').sql()
6791        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6792
6793    Args:
6794        expression: the SQL code strings to parse.
6795            If an Expression instance is passed, this is used as-is.
6796        alias: the alias name to use.
6797        dialect: the dialect used to parse the input expression.
6798        **opts: other options to use to parse the input expressions.
6799
6800    Returns:
6801        A new Select instance with the subquery expression included.
6802    """
6803
6804    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6805    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

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):
6836def column(
6837    col,
6838    table=None,
6839    db=None,
6840    catalog=None,
6841    *,
6842    fields=None,
6843    quoted=None,
6844    copy=True,
6845):
6846    """
6847    Build a Column.
6848
6849    Args:
6850        col: Column name.
6851        table: Table name.
6852        db: Database name.
6853        catalog: Catalog name.
6854        fields: Additional fields using dots.
6855        quoted: Whether to force quotes on the column's identifiers.
6856        copy: Whether to copy identifiers if passed in.
6857
6858    Returns:
6859        The new Column instance.
6860    """
6861    this = Column(
6862        this=to_identifier(col, quoted=quoted, copy=copy),
6863        table=to_identifier(table, quoted=quoted, copy=copy),
6864        db=to_identifier(db, quoted=quoted, copy=copy),
6865        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6866    )
6867
6868    if fields:
6869        this = Dot.build(
6870            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
6871        )
6872    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:
6875def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6876    """Cast an expression to a data type.
6877
6878    Example:
6879        >>> cast('x + 1', 'int').sql()
6880        'CAST(x + 1 AS INT)'
6881
6882    Args:
6883        expression: The expression to cast.
6884        to: The datatype to cast to.
6885        copy: Whether to copy the supplied expressions.
6886
6887    Returns:
6888        The new Cast instance.
6889    """
6890    expr = maybe_parse(expression, copy=copy, **opts)
6891    data_type = DataType.build(to, copy=copy, **opts)
6892
6893    if expr.is_type(data_type):
6894        return expr
6895
6896    expr = Cast(this=expr, to=data_type)
6897    expr.type = data_type
6898
6899    return expr

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:
6902def table_(
6903    table: Identifier | str,
6904    db: t.Optional[Identifier | str] = None,
6905    catalog: t.Optional[Identifier | str] = None,
6906    quoted: t.Optional[bool] = None,
6907    alias: t.Optional[Identifier | str] = None,
6908) -> Table:
6909    """Build a Table.
6910
6911    Args:
6912        table: Table name.
6913        db: Database name.
6914        catalog: Catalog name.
6915        quote: Whether to force quotes on the table's identifiers.
6916        alias: Table's alias.
6917
6918    Returns:
6919        The new Table instance.
6920    """
6921    return Table(
6922        this=to_identifier(table, quoted=quoted) if table else None,
6923        db=to_identifier(db, quoted=quoted) if db else None,
6924        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6925        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6926    )

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:
6929def values(
6930    values: t.Iterable[t.Tuple[t.Any, ...]],
6931    alias: t.Optional[str] = None,
6932    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6933) -> Values:
6934    """Build VALUES statement.
6935
6936    Example:
6937        >>> values([(1, '2')]).sql()
6938        "VALUES (1, '2')"
6939
6940    Args:
6941        values: values statements that will be converted to SQL
6942        alias: optional alias
6943        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6944         If either are provided then an alias is also required.
6945
6946    Returns:
6947        Values: the Values expression object
6948    """
6949    if columns and not alias:
6950        raise ValueError("Alias is required when providing columns")
6951
6952    return Values(
6953        expressions=[convert(tup) for tup in values],
6954        alias=(
6955            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6956            if columns
6957            else (TableAlias(this=to_identifier(alias)) if alias else None)
6958        ),
6959    )

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:
6962def var(name: t.Optional[ExpOrStr]) -> Var:
6963    """Build a SQL variable.
6964
6965    Example:
6966        >>> repr(var('x'))
6967        'Var(this=x)'
6968
6969        >>> repr(var(column('x', table='y')))
6970        'Var(this=x)'
6971
6972    Args:
6973        name: The name of the var or an expression who's name will become the var.
6974
6975    Returns:
6976        The new variable node.
6977    """
6978    if not name:
6979        raise ValueError("Cannot convert empty name into var.")
6980
6981    if isinstance(name, Expression):
6982        name = name.name
6983    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, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
6986def rename_table(
6987    old_name: str | Table,
6988    new_name: str | Table,
6989    dialect: DialectType = None,
6990) -> AlterTable:
6991    """Build ALTER TABLE... RENAME... expression
6992
6993    Args:
6994        old_name: The old name of the table
6995        new_name: The new name of the table
6996        dialect: The dialect to parse the table.
6997
6998    Returns:
6999        Alter table expression
7000    """
7001    old_table = to_table(old_name, dialect=dialect)
7002    new_table = to_table(new_name, dialect=dialect)
7003    return AlterTable(
7004        this=old_table,
7005        actions=[
7006            RenameTable(this=new_table),
7007        ],
7008    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse 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, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7011def rename_column(
7012    table_name: str | Table,
7013    old_column_name: str | Column,
7014    new_column_name: str | Column,
7015    exists: t.Optional[bool] = None,
7016    dialect: DialectType = None,
7017) -> AlterTable:
7018    """Build ALTER TABLE... RENAME COLUMN... expression
7019
7020    Args:
7021        table_name: Name of the table
7022        old_column: The old name of the column
7023        new_column: The new name of the column
7024        exists: Whether to add the `IF EXISTS` clause
7025        dialect: The dialect to parse the table/column.
7026
7027    Returns:
7028        Alter table expression
7029    """
7030    table = to_table(table_name, dialect=dialect)
7031    old_column = to_column(old_column_name, dialect=dialect)
7032    new_column = to_column(new_column_name, dialect=dialect)
7033    return AlterTable(
7034        this=table,
7035        actions=[
7036            RenameColumn(this=old_column, to=new_column, exists=exists),
7037        ],
7038    )

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
  • dialect: The dialect to parse the table/column.
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
7041def convert(value: t.Any, copy: bool = False) -> Expression:
7042    """Convert a python value into an expression object.
7043
7044    Raises an error if a conversion is not possible.
7045
7046    Args:
7047        value: A python object.
7048        copy: Whether to copy `value` (only applies to Expressions and collections).
7049
7050    Returns:
7051        The equivalent expression object.
7052    """
7053    if isinstance(value, Expression):
7054        return maybe_copy(value, copy)
7055    if isinstance(value, str):
7056        return Literal.string(value)
7057    if isinstance(value, bool):
7058        return Boolean(this=value)
7059    if value is None or (isinstance(value, float) and math.isnan(value)):
7060        return null()
7061    if isinstance(value, numbers.Number):
7062        return Literal.number(value)
7063    if isinstance(value, bytes):
7064        return HexString(this=value.hex())
7065    if isinstance(value, datetime.datetime):
7066        datetime_literal = Literal.string(
7067            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7068                sep=" "
7069            )
7070        )
7071        return TimeStrToTime(this=datetime_literal)
7072    if isinstance(value, datetime.date):
7073        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7074        return DateStrToDate(this=date_literal)
7075    if isinstance(value, tuple):
7076        if hasattr(value, "_fields"):
7077            return Struct(
7078                expressions=[
7079                    PropertyEQ(
7080                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7081                    )
7082                    for k in value._fields
7083                ]
7084            )
7085        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7086    if isinstance(value, list):
7087        return Array(expressions=[convert(v, copy=copy) for v in value])
7088    if isinstance(value, dict):
7089        return Map(
7090            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7091            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7092        )
7093    if hasattr(value, "__dict__"):
7094        return Struct(
7095            expressions=[
7096                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7097                for k, v in value.__dict__.items()
7098            ]
7099        )
7100    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:

The equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
7103def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7104    """
7105    Replace children of an expression with the result of a lambda fun(child) -> exp.
7106    """
7107    for k, v in tuple(expression.args.items()):
7108        is_list_arg = type(v) is list
7109
7110        child_nodes = v if is_list_arg else [v]
7111        new_child_nodes = []
7112
7113        for cn in child_nodes:
7114            if isinstance(cn, Expression):
7115                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7116                    new_child_nodes.append(child_node)
7117            else:
7118                new_child_nodes.append(cn)
7119
7120        expression.set(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 replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
7123def replace_tree(
7124    expression: Expression,
7125    fun: t.Callable,
7126    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7127) -> Expression:
7128    """
7129    Replace an entire tree with the result of function calls on each node.
7130
7131    This will be traversed in reverse dfs, so leaves first.
7132    If new nodes are created as a result of function calls, they will also be traversed.
7133    """
7134    stack = list(expression.dfs(prune=prune))
7135
7136    while stack:
7137        node = stack.pop()
7138        new_node = fun(node)
7139
7140        if new_node is not node:
7141            node.replace(new_node)
7142
7143            if isinstance(new_node, Expression):
7144                stack.append(new_node)
7145
7146    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
7149def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7150    """
7151    Return all table names referenced through columns in an expression.
7152
7153    Example:
7154        >>> import sqlglot
7155        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7156        ['a', 'c']
7157
7158    Args:
7159        expression: expression to find table names.
7160        exclude: a table name to exclude
7161
7162    Returns:
7163        A list of unique names.
7164    """
7165    return {
7166        table
7167        for table in (column.table for column in expression.find_all(Column))
7168        if table and table != exclude
7169    }

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:
7172def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7173    """Get the full name of a table as a string.
7174
7175    Args:
7176        table: Table expression node or string.
7177        dialect: The dialect to generate the table name for.
7178        identify: Determines when an identifier should be quoted. Possible values are:
7179            False (default): Never quote, except in cases where it's mandatory by the dialect.
7180            True: Always quote.
7181
7182    Examples:
7183        >>> from sqlglot import exp, parse_one
7184        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7185        'a.b.c'
7186
7187    Returns:
7188        The table name.
7189    """
7190
7191    table = maybe_parse(table, into=Table, dialect=dialect)
7192
7193    if not table:
7194        raise ValueError(f"Cannot parse {table}")
7195
7196    return ".".join(
7197        (
7198            part.sql(dialect=dialect, identify=True, copy=False)
7199            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7200            else part.name
7201        )
7202        for part in table.parts
7203    )

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:
7206def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7207    """Returns a case normalized table name without quotes.
7208
7209    Args:
7210        table: the table to normalize
7211        dialect: the dialect to use for normalization rules
7212        copy: whether to copy the expression.
7213
7214    Examples:
7215        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7216        'A-B.c'
7217    """
7218    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7219
7220    return ".".join(
7221        p.name
7222        for p in normalize_identifiers(
7223            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7224        ).parts
7225    )

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:
7228def replace_tables(
7229    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7230) -> E:
7231    """Replace all tables in expression according to the mapping.
7232
7233    Args:
7234        expression: expression node to be transformed and replaced.
7235        mapping: mapping of table names.
7236        dialect: the dialect of the mapping table
7237        copy: whether to copy the expression.
7238
7239    Examples:
7240        >>> from sqlglot import exp, parse_one
7241        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7242        'SELECT * FROM c /* a.b */'
7243
7244    Returns:
7245        The mapped expression.
7246    """
7247
7248    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7249
7250    def _replace_tables(node: Expression) -> Expression:
7251        if isinstance(node, Table):
7252            original = normalize_table_name(node, dialect=dialect)
7253            new_name = mapping.get(original)
7254
7255            if new_name:
7256                table = to_table(
7257                    new_name,
7258                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7259                    dialect=dialect,
7260                )
7261                table.add_comments([original])
7262                return table
7263        return node
7264
7265    return expression.transform(_replace_tables, copy=copy)  # type: ignore

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:
7268def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7269    """Replace placeholders in an expression.
7270
7271    Args:
7272        expression: expression node to be transformed and replaced.
7273        args: positional names that will substitute unnamed placeholders in the given order.
7274        kwargs: keyword arguments that will substitute named placeholders.
7275
7276    Examples:
7277        >>> from sqlglot import exp, parse_one
7278        >>> replace_placeholders(
7279        ...     parse_one("select * from :tbl where ? = ?"),
7280        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7281        ... ).sql()
7282        "SELECT * FROM foo WHERE str_col = 'b'"
7283
7284    Returns:
7285        The mapped expression.
7286    """
7287
7288    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7289        if isinstance(node, Placeholder):
7290            if node.this:
7291                new_name = kwargs.get(node.this)
7292                if new_name is not None:
7293                    return convert(new_name)
7294            else:
7295                try:
7296                    return convert(next(args))
7297                except StopIteration:
7298                    pass
7299        return node
7300
7301    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:
7304def expand(
7305    expression: Expression,
7306    sources: t.Dict[str, Query],
7307    dialect: DialectType = None,
7308    copy: bool = True,
7309) -> Expression:
7310    """Transforms an expression by expanding all referenced sources into subqueries.
7311
7312    Examples:
7313        >>> from sqlglot import parse_one
7314        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7315        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7316
7317        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7318        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7319
7320    Args:
7321        expression: The expression to expand.
7322        sources: A dictionary of name to Queries.
7323        dialect: The dialect of the sources dict.
7324        copy: Whether to copy the expression during transformation. Defaults to True.
7325
7326    Returns:
7327        The transformed expression.
7328    """
7329    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7330
7331    def _expand(node: Expression):
7332        if isinstance(node, Table):
7333            name = normalize_table_name(node, dialect=dialect)
7334            source = sources.get(name)
7335            if source:
7336                subquery = source.subquery(node.alias or name)
7337                subquery.comments = [f"source: {name}"]
7338                return subquery.transform(_expand, copy=False)
7339        return node
7340
7341    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:
7344def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7345    """
7346    Returns a Func expression.
7347
7348    Examples:
7349        >>> func("abs", 5).sql()
7350        'ABS(5)'
7351
7352        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7353        'CAST(5 AS DOUBLE)'
7354
7355    Args:
7356        name: the name of the function to build.
7357        args: the args used to instantiate the function of interest.
7358        copy: whether to copy the argument expressions.
7359        dialect: the source dialect.
7360        kwargs: the kwargs used to instantiate the function of interest.
7361
7362    Note:
7363        The arguments `args` and `kwargs` are mutually exclusive.
7364
7365    Returns:
7366        An instance of the function of interest, or an anonymous function, if `name` doesn't
7367        correspond to an existing `sqlglot.expressions.Func` class.
7368    """
7369    if args and kwargs:
7370        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7371
7372    from sqlglot.dialects.dialect import Dialect
7373
7374    dialect = Dialect.get_or_raise(dialect)
7375
7376    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7377    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7378
7379    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7380    if constructor:
7381        if converted:
7382            if "dialect" in constructor.__code__.co_varnames:
7383                function = constructor(converted, dialect=dialect)
7384            else:
7385                function = constructor(converted)
7386        elif constructor.__name__ == "from_arg_list":
7387            function = constructor.__self__(**kwargs)  # type: ignore
7388        else:
7389            constructor = FUNCTION_BY_NAME.get(name.upper())
7390            if constructor:
7391                function = constructor(**kwargs)
7392            else:
7393                raise ValueError(
7394                    f"Unable to convert '{name}' into a Func. Either manually construct "
7395                    "the Func expression of interest or parse the function call."
7396                )
7397    else:
7398        kwargs = kwargs or {"expressions": converted}
7399        function = Anonymous(this=name, **kwargs)
7400
7401    for error_message in function.error_messages(converted):
7402        raise ValueError(error_message)
7403
7404    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:
7407def case(
7408    expression: t.Optional[ExpOrStr] = None,
7409    **opts,
7410) -> Case:
7411    """
7412    Initialize a CASE statement.
7413
7414    Example:
7415        case().when("a = 1", "foo").else_("bar")
7416
7417    Args:
7418        expression: Optionally, the input expression (not all dialects support this)
7419        **opts: Extra keyword arguments for parsing `expression`
7420    """
7421    if expression is not None:
7422        this = maybe_parse(expression, **opts)
7423    else:
7424        this = None
7425    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 array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7428def array(
7429    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7430) -> Array:
7431    """
7432    Returns an array.
7433
7434    Examples:
7435        >>> array(1, 'x').sql()
7436        'ARRAY(1, x)'
7437
7438    Args:
7439        expressions: the expressions to add to the array.
7440        copy: whether to copy the argument expressions.
7441        dialect: the source dialect.
7442        kwargs: the kwargs used to instantiate the function of interest.
7443
7444    Returns:
7445        An array expression.
7446    """
7447    return Array(
7448        expressions=[
7449            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7450            for expression in expressions
7451        ]
7452    )

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:
7455def tuple_(
7456    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7457) -> Tuple:
7458    """
7459    Returns an tuple.
7460
7461    Examples:
7462        >>> tuple_(1, 'x').sql()
7463        '(1, x)'
7464
7465    Args:
7466        expressions: the expressions to add to the tuple.
7467        copy: whether to copy the argument expressions.
7468        dialect: the source dialect.
7469        kwargs: the kwargs used to instantiate the function of interest.
7470
7471    Returns:
7472        A tuple expression.
7473    """
7474    return Tuple(
7475        expressions=[
7476            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7477            for expression in expressions
7478        ]
7479    )

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:
7482def true() -> Boolean:
7483    """
7484    Returns a true Boolean expression.
7485    """
7486    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7489def false() -> Boolean:
7490    """
7491    Returns a false Boolean expression.
7492    """
7493    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7496def null() -> Null:
7497    """
7498    Returns a Null expression.
7499    """
7500    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)