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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

expressions: List[Any]
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 []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
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 ""

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
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"]

Checks whether a Literal expression is a string.

is_number: bool
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"]

Checks whether a Literal expression is a number.

is_int: bool
179    @property
180    def is_int(self) -> bool:
181        """
182        Checks whether a Literal expression is an integer.
183        """
184        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
186    @property
187    def is_star(self) -> bool:
188        """Checks whether an expression is a star."""
189        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
200    @property
201    def alias_column_names(self) -> t.List[str]:
202        table_alias = self.args.get("alias")
203        if not table_alias:
204            return []
205        return [c.name for c in table_alias.args.get("columns") or []]
name: str
207    @property
208    def name(self) -> str:
209        return self.text("this")
alias_or_name: str
211    @property
212    def alias_or_name(self) -> str:
213        return self.alias or self.name
output_name: str
215    @property
216    def output_name(self) -> str:
217        """
218        Name of the output column if this expression is a selection.
219
220        If the Expression has no output name, an empty string is returned.
221
222        Example:
223            >>> from sqlglot import parse_one
224            >>> parse_one("SELECT a").expressions[0].output_name
225            'a'
226            >>> parse_one("SELECT b AS c").expressions[0].output_name
227            'c'
228            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
229            ''
230        """
231        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]
233    @property
234    def type(self) -> t.Optional[DataType]:
235        return self._type
def is_type(self, *dtypes) -> bool:
243    def is_type(self, *dtypes) -> bool:
244        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
246    def is_leaf(self) -> bool:
247        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
249    @property
250    def meta(self) -> t.Dict[str, t.Any]:
251        if self._meta is None:
252            self._meta = {}
253        return self._meta
def copy(self):
289    def copy(self):
290        """
291        Returns a deep copy of the expression.
292        """
293        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
295    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
296        if self.comments is None:
297            self.comments = []
298        if comments:
299            for comment in comments:
300                _, *meta = comment.split(SQLGLOT_META)
301                if meta:
302                    for kv in "".join(meta).split(","):
303                        k, *v = kv.split("=")
304                        value = v[0].strip() if v else True
305                        self.meta[k.strip()] = value
306                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
308    def append(self, arg_key: str, value: t.Any) -> None:
309        """
310        Appends value to arg_key if it's a list or sets it as a new list.
311
312        Args:
313            arg_key (str): name of the list expression arg
314            value (Any): value to append to the list
315        """
316        if type(self.args.get(arg_key)) is not list:
317            self.args[arg_key] = []
318        self._set_parent(arg_key, value)
319        values = self.args[arg_key]
320        if hasattr(value, "parent"):
321            value.index = len(values)
322        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:
324    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
325        """
326        Sets arg_key to value.
327
328        Args:
329            arg_key: name of the expression arg.
330            value: value to set the arg to.
331            index: if the arg is a list, this specifies what position to add the value in it.
332        """
333        if index is not None:
334            expressions = self.args.get(arg_key) or []
335
336            if seq_get(expressions, index) is None:
337                return
338            if value is None:
339                expressions.pop(index)
340                for v in expressions[index:]:
341                    v.index = v.index - 1
342                return
343
344            if isinstance(value, list):
345                expressions.pop(index)
346                expressions[index:index] = value
347            else:
348                expressions[index] = value
349
350            value = expressions
351        elif value is None:
352            self.args.pop(arg_key, None)
353            return
354
355        self.args[arg_key] = value
356        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
370    @property
371    def depth(self) -> int:
372        """
373        Returns the depth of this tree.
374        """
375        if self.parent:
376            return self.parent.depth + 1
377        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
379    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
380        """Yields the key and expression for all arguments, exploding list args."""
381        # remove tuple when python 3.7 is deprecated
382        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
383            if type(vs) is list:
384                for v in reversed(vs) if reverse else vs:
385                    if hasattr(v, "parent"):
386                        yield v
387            else:
388                if hasattr(vs, "parent"):
389                    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]:
391    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
392        """
393        Returns the first node in this tree which matches at least one of
394        the specified types.
395
396        Args:
397            expression_types: the expression type(s) to match.
398            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
399
400        Returns:
401            The node which matches the criteria or None if no such node was found.
402        """
403        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]:
405    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
406        """
407        Returns a generator object which visits all nodes in this tree and only
408        yields those that match at least one of the specified expression types.
409
410        Args:
411            expression_types: the expression type(s) to match.
412            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
413
414        Returns:
415            The generator object.
416        """
417        for expression in self.walk(bfs=bfs):
418            if isinstance(expression, expression_types):
419                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]:
421    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
422        """
423        Returns a nearest parent matching expression_types.
424
425        Args:
426            expression_types: the expression type(s) to match.
427
428        Returns:
429            The parent node.
430        """
431        ancestor = self.parent
432        while ancestor and not isinstance(ancestor, expression_types):
433            ancestor = ancestor.parent
434        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]
436    @property
437    def parent_select(self) -> t.Optional[Select]:
438        """
439        Returns the parent select statement.
440        """
441        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
443    @property
444    def same_parent(self) -> bool:
445        """Returns if the parent is the same class as itself."""
446        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
448    def root(self) -> Expression:
449        """
450        Returns the root expression of this tree.
451        """
452        expression = self
453        while expression.parent:
454            expression = expression.parent
455        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
457    def walk(
458        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
459    ) -> t.Iterator[Expression]:
460        """
461        Returns a generator object which visits all nodes in this tree.
462
463        Args:
464            bfs: if set to True the BFS traversal order will be applied,
465                otherwise the DFS traversal will be used instead.
466            prune: callable that returns True if the generator should stop traversing
467                this branch of the tree.
468
469        Returns:
470            the generator object.
471        """
472        if bfs:
473            yield from self.bfs(prune=prune)
474        else:
475            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]:
477    def dfs(
478        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
479    ) -> t.Iterator[Expression]:
480        """
481        Returns a generator object which visits all nodes in this tree in
482        the DFS (Depth-first) order.
483
484        Returns:
485            The generator object.
486        """
487        stack = [self]
488
489        while stack:
490            node = stack.pop()
491
492            yield node
493
494            if prune and prune(node):
495                continue
496
497            for v in node.iter_expressions(reverse=True):
498                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]:
500    def bfs(
501        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
502    ) -> t.Iterator[Expression]:
503        """
504        Returns a generator object which visits all nodes in this tree in
505        the BFS (Breadth-first) order.
506
507        Returns:
508            The generator object.
509        """
510        queue = deque([self])
511
512        while queue:
513            node = queue.popleft()
514
515            yield node
516
517            if prune and prune(node):
518                continue
519
520            for v in node.iter_expressions():
521                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):
523    def unnest(self):
524        """
525        Returns the first non parenthesis child or self.
526        """
527        expression = self
528        while type(expression) is Paren:
529            expression = expression.this
530        return expression

Returns the first non parenthesis child or self.

def unalias(self):
532    def unalias(self):
533        """
534        Returns the inner expression if this is an Alias.
535        """
536        if isinstance(self, Alias):
537            return self.this
538        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
540    def unnest_operands(self):
541        """
542        Returns unnested operands as a tuple.
543        """
544        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
546    def flatten(self, unnest=True):
547        """
548        Returns a generator which yields child nodes whose parents are the same class.
549
550        A AND B AND C -> [A, B, C]
551        """
552        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
553            if type(node) is not self.__class__:
554                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:
562    def to_s(self) -> str:
563        """
564        Same as __repr__, but includes additional information which can be useful
565        for debugging, like empty or missing args and the AST nodes' object IDs.
566        """
567        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:
569    def sql(self, dialect: DialectType = None, **opts) -> str:
570        """
571        Returns SQL string representation of this tree.
572
573        Args:
574            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
575            opts: other `sqlglot.generator.Generator` options.
576
577        Returns:
578            The SQL string.
579        """
580        from sqlglot.dialects import Dialect
581
582        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:
584    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
585        """
586        Visits all tree nodes (excluding already transformed ones)
587        and applies the given transformation function to each node.
588
589        Args:
590            fun: a function which takes a node as an argument and returns a
591                new transformed node or the same node without modifications. If the function
592                returns None, then the corresponding node will be removed from the syntax tree.
593            copy: if set to True a new tree instance is constructed, otherwise the tree is
594                modified in place.
595
596        Returns:
597            The transformed tree.
598        """
599        root = None
600        new_node = None
601
602        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
603            parent, arg_key, index = node.parent, node.arg_key, node.index
604            new_node = fun(node, *args, **kwargs)
605
606            if not root:
607                root = new_node
608            elif new_node is not node:
609                parent.set(arg_key, new_node, index)
610
611        assert root
612        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):
620    def replace(self, expression):
621        """
622        Swap out this expression with a new expression.
623
624        For example::
625
626            >>> tree = Select().select("x").from_("tbl")
627            >>> tree.find(Column).replace(column("y"))
628            Column(
629              this=Identifier(this=y, quoted=False))
630            >>> tree.sql()
631            'SELECT y FROM tbl'
632
633        Args:
634            expression: new node
635
636        Returns:
637            The new expression or expressions.
638        """
639        parent = self.parent
640
641        if not parent or parent is expression:
642            return expression
643
644        key = self.arg_key
645        value = parent.args.get(key)
646
647        if type(expression) is list and isinstance(value, Expression):
648            # We are trying to replace an Expression with a list, so it's assumed that
649            # the intention was to really replace the parent of this expression.
650            value.parent.replace(expression)
651        else:
652            parent.set(key, expression, self.index)
653
654        if expression is not self:
655            self.parent = None
656            self.arg_key = None
657            self.index = None
658
659        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:
661    def pop(self: E) -> E:
662        """
663        Remove this expression from its AST.
664
665        Returns:
666            The popped expression.
667        """
668        self.replace(None)
669        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
731    @classmethod
732    def load(cls, obj):
733        """
734        Load a dict (as returned by `Expression.dump`) into an Expression instance.
735        """
736        from sqlglot.serde import load
737
738        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:
740    def and_(
741        self,
742        *expressions: t.Optional[ExpOrStr],
743        dialect: DialectType = None,
744        copy: bool = True,
745        **opts,
746    ) -> Condition:
747        """
748        AND this condition with one or multiple expressions.
749
750        Example:
751            >>> condition("x=1").and_("y=1").sql()
752            'x = 1 AND y = 1'
753
754        Args:
755            *expressions: the SQL code strings to parse.
756                If an `Expression` instance is passed, it will be used as-is.
757            dialect: the dialect used to parse the input expression.
758            copy: whether to copy the involved expressions (only applies to Expressions).
759            opts: other options to use to parse the input expressions.
760
761        Returns:
762            The new And condition.
763        """
764        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:
766    def or_(
767        self,
768        *expressions: t.Optional[ExpOrStr],
769        dialect: DialectType = None,
770        copy: bool = True,
771        **opts,
772    ) -> Condition:
773        """
774        OR this condition with one or multiple expressions.
775
776        Example:
777            >>> condition("x=1").or_("y=1").sql()
778            'x = 1 OR y = 1'
779
780        Args:
781            *expressions: the SQL code strings to parse.
782                If an `Expression` instance is passed, it will be used as-is.
783            dialect: the dialect used to parse the input expression.
784            copy: whether to copy the involved expressions (only applies to Expressions).
785            opts: other options to use to parse the input expressions.
786
787        Returns:
788            The new Or condition.
789        """
790        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):
792    def not_(self, copy: bool = True):
793        """
794        Wrap this condition with NOT.
795
796        Example:
797            >>> condition("x=1").not_().sql()
798            'NOT x = 1'
799
800        Args:
801            copy: whether to copy this object.
802
803        Returns:
804            The new Not instance.
805        """
806        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:
808    def as_(
809        self,
810        alias: str | Identifier,
811        quoted: t.Optional[bool] = None,
812        dialect: DialectType = None,
813        copy: bool = True,
814        **opts,
815    ) -> Alias:
816        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:
841    def isin(
842        self,
843        *expressions: t.Any,
844        query: t.Optional[ExpOrStr] = None,
845        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
846        copy: bool = True,
847        **opts,
848    ) -> In:
849        return In(
850            this=maybe_copy(self, copy),
851            expressions=[convert(e, copy=copy) for e in expressions],
852            query=maybe_parse(query, copy=copy, **opts) if query else None,
853            unnest=(
854                Unnest(
855                    expressions=[
856                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
857                        for e in ensure_list(unnest)
858                    ]
859                )
860                if unnest
861                else None
862            ),
863        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
865    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
866        return Between(
867            this=maybe_copy(self, copy),
868            low=convert(low, copy=copy, **opts),
869            high=convert(high, copy=copy, **opts),
870        )
def is_( self, other: Union[str, Expression]) -> Is:
872    def is_(self, other: ExpOrStr) -> Is:
873        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
875    def like(self, other: ExpOrStr) -> Like:
876        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
878    def ilike(self, other: ExpOrStr) -> ILike:
879        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
881    def eq(self, other: t.Any) -> EQ:
882        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
884    def neq(self, other: t.Any) -> NEQ:
885        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
887    def rlike(self, other: ExpOrStr) -> RegexpLike:
888        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
890    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
891        div = self._binop(Div, other)
892        div.args["typed"] = typed
893        div.args["safe"] = safe
894        return div
def asc(self, nulls_first: bool = True) -> Ordered:
896    def asc(self, nulls_first: bool = True) -> Ordered:
897        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
899    def desc(self, nulls_first: bool = False) -> Ordered:
900        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):
983class Condition(Expression):
984    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
991class DerivedTable(Expression):
992    @property
993    def selects(self) -> t.List[Expression]:
994        return self.this.selects if isinstance(self.this, Query) else []
995
996    @property
997    def named_selects(self) -> t.List[str]:
998        return [select.output_name for select in self.selects]
selects: List[Expression]
992    @property
993    def selects(self) -> t.List[Expression]:
994        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
996    @property
997    def named_selects(self) -> t.List[str]:
998        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1001class Query(Expression):
1002    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1003        """
1004        Returns a `Subquery` that wraps around this query.
1005
1006        Example:
1007            >>> subquery = Select().select("x").from_("tbl").subquery()
1008            >>> Select().select("x").from_(subquery).sql()
1009            'SELECT x FROM (SELECT x FROM tbl)'
1010
1011        Args:
1012            alias: an optional alias for the subquery.
1013            copy: if `False`, modify this expression instance in-place.
1014        """
1015        instance = maybe_copy(self, copy)
1016        if not isinstance(alias, Expression):
1017            alias = TableAlias(this=to_identifier(alias)) if alias else None
1018
1019        return Subquery(this=instance, alias=alias)
1020
1021    def limit(
1022        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1023    ) -> Select:
1024        """
1025        Adds a LIMIT clause to this query.
1026
1027        Example:
1028            >>> select("1").union(select("1")).limit(1).sql()
1029            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1030
1031        Args:
1032            expression: the SQL code string to parse.
1033                This can also be an integer.
1034                If a `Limit` instance is passed, it will be used as-is.
1035                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1036            dialect: the dialect used to parse the input expression.
1037            copy: if `False`, modify this expression instance in-place.
1038            opts: other options to use to parse the input expressions.
1039
1040        Returns:
1041            A limited Select expression.
1042        """
1043        return (
1044            select("*")
1045            .from_(self.subquery(alias="_l_0", copy=copy))
1046            .limit(expression, dialect=dialect, copy=False, **opts)
1047        )
1048
1049    @property
1050    def ctes(self) -> t.List[CTE]:
1051        """Returns a list of all the CTEs attached to this query."""
1052        with_ = self.args.get("with")
1053        return with_.expressions if with_ else []
1054
1055    @property
1056    def selects(self) -> t.List[Expression]:
1057        """Returns the query's projections."""
1058        raise NotImplementedError("Query objects must implement `selects`")
1059
1060    @property
1061    def named_selects(self) -> t.List[str]:
1062        """Returns the output names of the query's projections."""
1063        raise NotImplementedError("Query objects must implement `named_selects`")
1064
1065    def select(
1066        self: Q,
1067        *expressions: t.Optional[ExpOrStr],
1068        append: bool = True,
1069        dialect: DialectType = None,
1070        copy: bool = True,
1071        **opts,
1072    ) -> Q:
1073        """
1074        Append to or set the SELECT expressions.
1075
1076        Example:
1077            >>> Select().select("x", "y").sql()
1078            'SELECT x, y'
1079
1080        Args:
1081            *expressions: the SQL code strings to parse.
1082                If an `Expression` instance is passed, it will be used as-is.
1083            append: if `True`, add to any existing expressions.
1084                Otherwise, this resets the expressions.
1085            dialect: the dialect used to parse the input expressions.
1086            copy: if `False`, modify this expression instance in-place.
1087            opts: other options to use to parse the input expressions.
1088
1089        Returns:
1090            The modified Query expression.
1091        """
1092        raise NotImplementedError("Query objects must implement `select`")
1093
1094    def with_(
1095        self: Q,
1096        alias: ExpOrStr,
1097        as_: ExpOrStr,
1098        recursive: t.Optional[bool] = None,
1099        append: bool = True,
1100        dialect: DialectType = None,
1101        copy: bool = True,
1102        **opts,
1103    ) -> Q:
1104        """
1105        Append to or set the common table expressions.
1106
1107        Example:
1108            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1109            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1110
1111        Args:
1112            alias: the SQL code string to parse as the table name.
1113                If an `Expression` instance is passed, this is used as-is.
1114            as_: the SQL code string to parse as the table expression.
1115                If an `Expression` instance is passed, it will be used as-is.
1116            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1117            append: if `True`, add to any existing expressions.
1118                Otherwise, this resets the expressions.
1119            dialect: the dialect used to parse the input expression.
1120            copy: if `False`, modify this expression instance in-place.
1121            opts: other options to use to parse the input expressions.
1122
1123        Returns:
1124            The modified expression.
1125        """
1126        return _apply_cte_builder(
1127            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1128        )
1129
1130    def union(
1131        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1132    ) -> Union:
1133        """
1134        Builds a UNION expression.
1135
1136        Example:
1137            >>> import sqlglot
1138            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1139            'SELECT * FROM foo UNION SELECT * FROM bla'
1140
1141        Args:
1142            expression: the SQL code string.
1143                If an `Expression` instance is passed, it will be used as-is.
1144            distinct: set the DISTINCT flag if and only if this is true.
1145            dialect: the dialect used to parse the input expression.
1146            opts: other options to use to parse the input expressions.
1147
1148        Returns:
1149            The new Union expression.
1150        """
1151        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1152
1153    def intersect(
1154        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1155    ) -> Intersect:
1156        """
1157        Builds an INTERSECT expression.
1158
1159        Example:
1160            >>> import sqlglot
1161            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1162            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1163
1164        Args:
1165            expression: the SQL code string.
1166                If an `Expression` instance is passed, it will be used as-is.
1167            distinct: set the DISTINCT flag if and only if this is true.
1168            dialect: the dialect used to parse the input expression.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The new Intersect expression.
1173        """
1174        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1175
1176    def except_(
1177        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1178    ) -> Except:
1179        """
1180        Builds an EXCEPT expression.
1181
1182        Example:
1183            >>> import sqlglot
1184            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1185            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1186
1187        Args:
1188            expression: the SQL code string.
1189                If an `Expression` instance is passed, it will be used as-is.
1190            distinct: set the DISTINCT flag if and only if this is true.
1191            dialect: the dialect used to parse the input expression.
1192            opts: other options to use to parse the input expressions.
1193
1194        Returns:
1195            The new Except expression.
1196        """
1197        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1002    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1003        """
1004        Returns a `Subquery` that wraps around this query.
1005
1006        Example:
1007            >>> subquery = Select().select("x").from_("tbl").subquery()
1008            >>> Select().select("x").from_(subquery).sql()
1009            'SELECT x FROM (SELECT x FROM tbl)'
1010
1011        Args:
1012            alias: an optional alias for the subquery.
1013            copy: if `False`, modify this expression instance in-place.
1014        """
1015        instance = maybe_copy(self, copy)
1016        if not isinstance(alias, Expression):
1017            alias = TableAlias(this=to_identifier(alias)) if alias else None
1018
1019        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
1021    def limit(
1022        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1023    ) -> Select:
1024        """
1025        Adds a LIMIT clause to this query.
1026
1027        Example:
1028            >>> select("1").union(select("1")).limit(1).sql()
1029            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
1030
1031        Args:
1032            expression: the SQL code string to parse.
1033                This can also be an integer.
1034                If a `Limit` instance is passed, it will be used as-is.
1035                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1036            dialect: the dialect used to parse the input expression.
1037            copy: if `False`, modify this expression instance in-place.
1038            opts: other options to use to parse the input expressions.
1039
1040        Returns:
1041            A limited Select expression.
1042        """
1043        return (
1044            select("*")
1045            .from_(self.subquery(alias="_l_0", copy=copy))
1046            .limit(expression, dialect=dialect, copy=False, **opts)
1047        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

ctes: List[CTE]
1049    @property
1050    def ctes(self) -> t.List[CTE]:
1051        """Returns a list of all the CTEs attached to this query."""
1052        with_ = self.args.get("with")
1053        return with_.expressions if with_ else []

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

selects: List[Expression]
1055    @property
1056    def selects(self) -> t.List[Expression]:
1057        """Returns the query's projections."""
1058        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1060    @property
1061    def named_selects(self) -> t.List[str]:
1062        """Returns the output names of the query's projections."""
1063        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:
1065    def select(
1066        self: Q,
1067        *expressions: t.Optional[ExpOrStr],
1068        append: bool = True,
1069        dialect: DialectType = None,
1070        copy: bool = True,
1071        **opts,
1072    ) -> Q:
1073        """
1074        Append to or set the SELECT expressions.
1075
1076        Example:
1077            >>> Select().select("x", "y").sql()
1078            'SELECT x, y'
1079
1080        Args:
1081            *expressions: the SQL code strings to parse.
1082                If an `Expression` instance is passed, it will be used as-is.
1083            append: if `True`, add to any existing expressions.
1084                Otherwise, this resets the expressions.
1085            dialect: the dialect used to parse the input expressions.
1086            copy: if `False`, modify this expression instance in-place.
1087            opts: other options to use to parse the input expressions.
1088
1089        Returns:
1090            The modified Query expression.
1091        """
1092        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:
1094    def with_(
1095        self: Q,
1096        alias: ExpOrStr,
1097        as_: ExpOrStr,
1098        recursive: t.Optional[bool] = None,
1099        append: bool = True,
1100        dialect: DialectType = None,
1101        copy: bool = True,
1102        **opts,
1103    ) -> Q:
1104        """
1105        Append to or set the common table expressions.
1106
1107        Example:
1108            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1109            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1110
1111        Args:
1112            alias: the SQL code string to parse as the table name.
1113                If an `Expression` instance is passed, this is used as-is.
1114            as_: the SQL code string to parse as the table expression.
1115                If an `Expression` instance is passed, it will be used as-is.
1116            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1117            append: if `True`, add to any existing expressions.
1118                Otherwise, this resets the expressions.
1119            dialect: the dialect used to parse the input expression.
1120            copy: if `False`, modify this expression instance in-place.
1121            opts: other options to use to parse the input expressions.
1122
1123        Returns:
1124            The modified expression.
1125        """
1126        return _apply_cte_builder(
1127            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1128        )

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:
1130    def union(
1131        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1132    ) -> Union:
1133        """
1134        Builds a UNION expression.
1135
1136        Example:
1137            >>> import sqlglot
1138            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1139            'SELECT * FROM foo UNION SELECT * FROM bla'
1140
1141        Args:
1142            expression: the SQL code string.
1143                If an `Expression` instance is passed, it will be used as-is.
1144            distinct: set the DISTINCT flag if and only if this is true.
1145            dialect: the dialect used to parse the input expression.
1146            opts: other options to use to parse the input expressions.
1147
1148        Returns:
1149            The new Union expression.
1150        """
1151        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:
1153    def intersect(
1154        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1155    ) -> Intersect:
1156        """
1157        Builds an INTERSECT expression.
1158
1159        Example:
1160            >>> import sqlglot
1161            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1162            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1163
1164        Args:
1165            expression: the SQL code string.
1166                If an `Expression` instance is passed, it will be used as-is.
1167            distinct: set the DISTINCT flag if and only if this is true.
1168            dialect: the dialect used to parse the input expression.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The new Intersect expression.
1173        """
1174        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:
1176    def except_(
1177        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1178    ) -> Except:
1179        """
1180        Builds an EXCEPT expression.
1181
1182        Example:
1183            >>> import sqlglot
1184            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1185            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1186
1187        Args:
1188            expression: the SQL code string.
1189                If an `Expression` instance is passed, it will be used as-is.
1190            distinct: set the DISTINCT flag if and only if this is true.
1191            dialect: the dialect used to parse the input expression.
1192            opts: other options to use to parse the input expressions.
1193
1194        Returns:
1195            The new Except expression.
1196        """
1197        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):
1200class UDTF(DerivedTable):
1201    @property
1202    def selects(self) -> t.List[Expression]:
1203        alias = self.args.get("alias")
1204        return alias.columns if alias else []
selects: List[Expression]
1201    @property
1202    def selects(self) -> t.List[Expression]:
1203        alias = self.args.get("alias")
1204        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1207class Cache(Expression):
1208    arg_types = {
1209        "this": True,
1210        "lazy": False,
1211        "options": False,
1212        "expression": False,
1213    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1216class Uncache(Expression):
1217    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1220class Refresh(Expression):
1221    pass
key = 'refresh'
class DDL(Expression):
1224class DDL(Expression):
1225    @property
1226    def ctes(self) -> t.List[CTE]:
1227        """Returns a list of all the CTEs attached to this statement."""
1228        with_ = self.args.get("with")
1229        return with_.expressions if with_ else []
1230
1231    @property
1232    def selects(self) -> t.List[Expression]:
1233        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1234        return self.expression.selects if isinstance(self.expression, Query) else []
1235
1236    @property
1237    def named_selects(self) -> t.List[str]:
1238        """
1239        If this statement contains a query (e.g. a CTAS), this returns the output
1240        names of the query's projections.
1241        """
1242        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1225    @property
1226    def ctes(self) -> t.List[CTE]:
1227        """Returns a list of all the CTEs attached to this statement."""
1228        with_ = self.args.get("with")
1229        return with_.expressions if with_ else []

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

selects: List[Expression]
1231    @property
1232    def selects(self) -> t.List[Expression]:
1233        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1234        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]
1236    @property
1237    def named_selects(self) -> t.List[str]:
1238        """
1239        If this statement contains a query (e.g. a CTAS), this returns the output
1240        names of the query's projections.
1241        """
1242        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):
1245class DML(Expression):
1246    def returning(
1247        self,
1248        expression: ExpOrStr,
1249        dialect: DialectType = None,
1250        copy: bool = True,
1251        **opts,
1252    ) -> DML:
1253        """
1254        Set the RETURNING expression. Not supported by all dialects.
1255
1256        Example:
1257            >>> delete("tbl").returning("*", dialect="postgres").sql()
1258            'DELETE FROM tbl RETURNING *'
1259
1260        Args:
1261            expression: the SQL code strings to parse.
1262                If an `Expression` instance is passed, it will be used as-is.
1263            dialect: the dialect used to parse the input expressions.
1264            copy: if `False`, modify this expression instance in-place.
1265            opts: other options to use to parse the input expressions.
1266
1267        Returns:
1268            Delete: the modified expression.
1269        """
1270        return _apply_builder(
1271            expression=expression,
1272            instance=self,
1273            arg="returning",
1274            prefix="RETURNING",
1275            dialect=dialect,
1276            copy=copy,
1277            into=Returning,
1278            **opts,
1279        )
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:
1246    def returning(
1247        self,
1248        expression: ExpOrStr,
1249        dialect: DialectType = None,
1250        copy: bool = True,
1251        **opts,
1252    ) -> DML:
1253        """
1254        Set the RETURNING expression. Not supported by all dialects.
1255
1256        Example:
1257            >>> delete("tbl").returning("*", dialect="postgres").sql()
1258            'DELETE FROM tbl RETURNING *'
1259
1260        Args:
1261            expression: the SQL code strings to parse.
1262                If an `Expression` instance is passed, it will be used as-is.
1263            dialect: the dialect used to parse the input expressions.
1264            copy: if `False`, modify this expression instance in-place.
1265            opts: other options to use to parse the input expressions.
1266
1267        Returns:
1268            Delete: the modified expression.
1269        """
1270        return _apply_builder(
1271            expression=expression,
1272            instance=self,
1273            arg="returning",
1274            prefix="RETURNING",
1275            dialect=dialect,
1276            copy=copy,
1277            into=Returning,
1278            **opts,
1279        )

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):
1282class Create(DDL):
1283    arg_types = {
1284        "with": False,
1285        "this": True,
1286        "kind": True,
1287        "expression": False,
1288        "exists": False,
1289        "properties": False,
1290        "replace": False,
1291        "unique": False,
1292        "indexes": False,
1293        "no_schema_binding": False,
1294        "begin": False,
1295        "end": False,
1296        "clone": False,
1297    }
1298
1299    @property
1300    def kind(self) -> t.Optional[str]:
1301        kind = self.args.get("kind")
1302        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]
1299    @property
1300    def kind(self) -> t.Optional[str]:
1301        kind = self.args.get("kind")
1302        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1305class SequenceProperties(Expression):
1306    arg_types = {
1307        "increment": False,
1308        "minvalue": False,
1309        "maxvalue": False,
1310        "cache": False,
1311        "start": False,
1312        "owned": False,
1313        "options": False,
1314    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1317class TruncateTable(Expression):
1318    arg_types = {
1319        "expressions": True,
1320        "is_database": False,
1321        "exists": False,
1322        "only": False,
1323        "cluster": False,
1324        "identity": False,
1325        "option": False,
1326        "partition": False,
1327    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1333class Clone(Expression):
1334    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1337class Describe(Expression):
1338    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):
1341class Kill(Expression):
1342    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1345class Pragma(Expression):
1346    pass
key = 'pragma'
class Set(Expression):
1349class Set(Expression):
1350    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1353class Heredoc(Expression):
1354    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1357class SetItem(Expression):
1358    arg_types = {
1359        "this": False,
1360        "expressions": False,
1361        "kind": False,
1362        "collate": False,  # MySQL SET NAMES statement
1363        "global": False,
1364    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1367class Show(Expression):
1368    arg_types = {
1369        "this": True,
1370        "history": False,
1371        "terse": False,
1372        "target": False,
1373        "offset": False,
1374        "starts_with": False,
1375        "limit": False,
1376        "from": False,
1377        "like": False,
1378        "where": False,
1379        "db": False,
1380        "scope": False,
1381        "scope_kind": False,
1382        "full": False,
1383        "mutex": False,
1384        "query": False,
1385        "channel": False,
1386        "global": False,
1387        "log": False,
1388        "position": False,
1389        "types": False,
1390    }
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):
1393class UserDefinedFunction(Expression):
1394    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1397class CharacterSet(Expression):
1398    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1401class With(Expression):
1402    arg_types = {"expressions": True, "recursive": False}
1403
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1409class WithinGroup(Expression):
1410    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1415class CTE(DerivedTable):
1416    arg_types = {
1417        "this": True,
1418        "alias": True,
1419        "scalar": False,
1420        "materialized": False,
1421    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class TableAlias(Expression):
1424class TableAlias(Expression):
1425    arg_types = {"this": False, "columns": False}
1426
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1432class BitString(Condition):
1433    pass
key = 'bitstring'
class HexString(Condition):
1436class HexString(Condition):
1437    pass
key = 'hexstring'
class ByteString(Condition):
1440class ByteString(Condition):
1441    pass
key = 'bytestring'
class RawString(Condition):
1444class RawString(Condition):
1445    pass
key = 'rawstring'
class UnicodeString(Condition):
1448class UnicodeString(Condition):
1449    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1452class Column(Condition):
1453    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1454
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
1458
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
1462
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
1466
1467    @property
1468    def output_name(self) -> str:
1469        return self.name
1470
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]
1479
1480    def to_dot(self) -> Dot | Identifier:
1481        """Converts the column into a dot expression."""
1482        parts = self.parts
1483        parent = self.parent
1484
1485        while parent:
1486            if isinstance(parent, Dot):
1487                parts.append(parent.expression)
1488            parent = parent.parent
1489
1490        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
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
db: str
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
catalog: str
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
output_name: str
1467    @property
1468    def output_name(self) -> str:
1469        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]
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]

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

def to_dot(self) -> Dot | Identifier:
1480    def to_dot(self) -> Dot | Identifier:
1481        """Converts the column into a dot expression."""
1482        parts = self.parts
1483        parent = self.parent
1484
1485        while parent:
1486            if isinstance(parent, Dot):
1487                parts.append(parent.expression)
1488            parent = parent.parent
1489
1490        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1493class ColumnPosition(Expression):
1494    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1497class ColumnDef(Expression):
1498    arg_types = {
1499        "this": True,
1500        "kind": False,
1501        "constraints": False,
1502        "exists": False,
1503        "position": False,
1504    }
1505
1506    @property
1507    def constraints(self) -> t.List[ColumnConstraint]:
1508        return self.args.get("constraints") or []
1509
1510    @property
1511    def kind(self) -> t.Optional[DataType]:
1512        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1506    @property
1507    def constraints(self) -> t.List[ColumnConstraint]:
1508        return self.args.get("constraints") or []
kind: Optional[DataType]
1510    @property
1511    def kind(self) -> t.Optional[DataType]:
1512        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1515class AlterColumn(Expression):
1516    arg_types = {
1517        "this": True,
1518        "dtype": False,
1519        "collate": False,
1520        "using": False,
1521        "default": False,
1522        "drop": False,
1523        "comment": False,
1524    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False}
key = 'altercolumn'
class RenameColumn(Expression):
1527class RenameColumn(Expression):
1528    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1531class RenameTable(Expression):
1532    pass
key = 'renametable'
class SwapTable(Expression):
1535class SwapTable(Expression):
1536    pass
key = 'swaptable'
class Comment(Expression):
1539class Comment(Expression):
1540    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1543class Comprehension(Expression):
1544    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):
1548class MergeTreeTTLAction(Expression):
1549    arg_types = {
1550        "this": True,
1551        "delete": False,
1552        "recompress": False,
1553        "to_disk": False,
1554        "to_volume": False,
1555    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1559class MergeTreeTTL(Expression):
1560    arg_types = {
1561        "expressions": True,
1562        "where": False,
1563        "group": False,
1564        "aggregates": False,
1565    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1569class IndexConstraintOption(Expression):
1570    arg_types = {
1571        "key_block_size": False,
1572        "using": False,
1573        "parser": False,
1574        "comment": False,
1575        "visible": False,
1576        "engine_attr": False,
1577        "secondary_engine_attr": False,
1578    }
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):
1581class ColumnConstraint(Expression):
1582    arg_types = {"this": False, "kind": True}
1583
1584    @property
1585    def kind(self) -> ColumnConstraintKind:
1586        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1584    @property
1585    def kind(self) -> ColumnConstraintKind:
1586        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1589class ColumnConstraintKind(Expression):
1590    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1593class AutoIncrementColumnConstraint(ColumnConstraintKind):
1594    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1597class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1598    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1601class CaseSpecificColumnConstraint(ColumnConstraintKind):
1602    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1605class CharacterSetColumnConstraint(ColumnConstraintKind):
1606    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1609class CheckColumnConstraint(ColumnConstraintKind):
1610    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1613class ClusteredColumnConstraint(ColumnConstraintKind):
1614    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1617class CollateColumnConstraint(ColumnConstraintKind):
1618    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1621class CommentColumnConstraint(ColumnConstraintKind):
1622    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1625class CompressColumnConstraint(ColumnConstraintKind):
1626    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1629class DateFormatColumnConstraint(ColumnConstraintKind):
1630    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1633class DefaultColumnConstraint(ColumnConstraintKind):
1634    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1637class EncodeColumnConstraint(ColumnConstraintKind):
1638    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1642class ExcludeColumnConstraint(ColumnConstraintKind):
1643    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1646class EphemeralColumnConstraint(ColumnConstraintKind):
1647    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1650class WithOperator(Expression):
1651    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1654class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1655    # this: True -> ALWAYS, this: False -> BY DEFAULT
1656    arg_types = {
1657        "this": False,
1658        "expression": False,
1659        "on_null": False,
1660        "start": False,
1661        "increment": False,
1662        "minvalue": False,
1663        "maxvalue": False,
1664        "cycle": False,
1665    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1668class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1669    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1674class IndexColumnConstraint(ColumnConstraintKind):
1675    arg_types = {
1676        "this": False,
1677        "expressions": False,
1678        "kind": False,
1679        "index_type": False,
1680        "options": False,
1681        "expression": False,  # Clickhouse
1682        "granularity": False,
1683    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1686class InlineLengthColumnConstraint(ColumnConstraintKind):
1687    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1690class NonClusteredColumnConstraint(ColumnConstraintKind):
1691    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1694class NotForReplicationColumnConstraint(ColumnConstraintKind):
1695    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1698class NotNullColumnConstraint(ColumnConstraintKind):
1699    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1703class OnUpdateColumnConstraint(ColumnConstraintKind):
1704    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1708class TransformColumnConstraint(ColumnConstraintKind):
1709    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1712class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1713    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1716class TitleColumnConstraint(ColumnConstraintKind):
1717    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1720class UniqueColumnConstraint(ColumnConstraintKind):
1721    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):
1724class UppercaseColumnConstraint(ColumnConstraintKind):
1725    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1728class PathColumnConstraint(ColumnConstraintKind):
1729    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1734class ComputedColumnConstraint(ColumnConstraintKind):
1735    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1738class Constraint(Expression):
1739    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1742class Delete(DML):
1743    arg_types = {
1744        "with": False,
1745        "this": False,
1746        "using": False,
1747        "where": False,
1748        "returning": False,
1749        "limit": False,
1750        "tables": False,  # Multiple-Table Syntax (MySQL)
1751    }
1752
1753    def delete(
1754        self,
1755        table: ExpOrStr,
1756        dialect: DialectType = None,
1757        copy: bool = True,
1758        **opts,
1759    ) -> Delete:
1760        """
1761        Create a DELETE expression or replace the table on an existing DELETE expression.
1762
1763        Example:
1764            >>> delete("tbl").sql()
1765            'DELETE FROM tbl'
1766
1767        Args:
1768            table: the table from which to delete.
1769            dialect: the dialect used to parse the input expression.
1770            copy: if `False`, modify this expression instance in-place.
1771            opts: other options to use to parse the input expressions.
1772
1773        Returns:
1774            Delete: the modified expression.
1775        """
1776        return _apply_builder(
1777            expression=table,
1778            instance=self,
1779            arg="this",
1780            dialect=dialect,
1781            into=Table,
1782            copy=copy,
1783            **opts,
1784        )
1785
1786    def where(
1787        self,
1788        *expressions: t.Optional[ExpOrStr],
1789        append: bool = True,
1790        dialect: DialectType = None,
1791        copy: bool = True,
1792        **opts,
1793    ) -> Delete:
1794        """
1795        Append to or set the WHERE expressions.
1796
1797        Example:
1798            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1799            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1800
1801        Args:
1802            *expressions: the SQL code strings to parse.
1803                If an `Expression` instance is passed, it will be used as-is.
1804                Multiple expressions are combined with an AND operator.
1805            append: if `True`, AND the new expressions to any existing expression.
1806                Otherwise, this resets the expression.
1807            dialect: the dialect used to parse the input expressions.
1808            copy: if `False`, modify this expression instance in-place.
1809            opts: other options to use to parse the input expressions.
1810
1811        Returns:
1812            Delete: the modified expression.
1813        """
1814        return _apply_conjunction_builder(
1815            *expressions,
1816            instance=self,
1817            arg="where",
1818            append=append,
1819            into=Where,
1820            dialect=dialect,
1821            copy=copy,
1822            **opts,
1823        )
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:
1753    def delete(
1754        self,
1755        table: ExpOrStr,
1756        dialect: DialectType = None,
1757        copy: bool = True,
1758        **opts,
1759    ) -> Delete:
1760        """
1761        Create a DELETE expression or replace the table on an existing DELETE expression.
1762
1763        Example:
1764            >>> delete("tbl").sql()
1765            'DELETE FROM tbl'
1766
1767        Args:
1768            table: the table from which to delete.
1769            dialect: the dialect used to parse the input expression.
1770            copy: if `False`, modify this expression instance in-place.
1771            opts: other options to use to parse the input expressions.
1772
1773        Returns:
1774            Delete: the modified expression.
1775        """
1776        return _apply_builder(
1777            expression=table,
1778            instance=self,
1779            arg="this",
1780            dialect=dialect,
1781            into=Table,
1782            copy=copy,
1783            **opts,
1784        )

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:
1786    def where(
1787        self,
1788        *expressions: t.Optional[ExpOrStr],
1789        append: bool = True,
1790        dialect: DialectType = None,
1791        copy: bool = True,
1792        **opts,
1793    ) -> Delete:
1794        """
1795        Append to or set the WHERE expressions.
1796
1797        Example:
1798            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1799            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1800
1801        Args:
1802            *expressions: the SQL code strings to parse.
1803                If an `Expression` instance is passed, it will be used as-is.
1804                Multiple expressions are combined with an AND operator.
1805            append: if `True`, AND the new expressions to any existing expression.
1806                Otherwise, this resets the expression.
1807            dialect: the dialect used to parse the input expressions.
1808            copy: if `False`, modify this expression instance in-place.
1809            opts: other options to use to parse the input expressions.
1810
1811        Returns:
1812            Delete: the modified expression.
1813        """
1814        return _apply_conjunction_builder(
1815            *expressions,
1816            instance=self,
1817            arg="where",
1818            append=append,
1819            into=Where,
1820            dialect=dialect,
1821            copy=copy,
1822            **opts,
1823        )

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):
1826class Drop(Expression):
1827    arg_types = {
1828        "this": False,
1829        "kind": False,
1830        "expressions": False,
1831        "exists": False,
1832        "temporary": False,
1833        "materialized": False,
1834        "cascade": False,
1835        "constraints": False,
1836        "purge": False,
1837    }
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):
1840class Filter(Expression):
1841    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1844class Check(Expression):
1845    pass
key = 'check'
class Connect(Expression):
1849class Connect(Expression):
1850    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class Prior(Expression):
1853class Prior(Expression):
1854    pass
key = 'prior'
class Directory(Expression):
1857class Directory(Expression):
1858    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1859    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1862class ForeignKey(Expression):
1863    arg_types = {
1864        "expressions": True,
1865        "reference": False,
1866        "delete": False,
1867        "update": False,
1868    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1871class ColumnPrefix(Expression):
1872    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1875class PrimaryKey(Expression):
1876    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1881class Into(Expression):
1882    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1885class From(Expression):
1886    @property
1887    def name(self) -> str:
1888        return self.this.name
1889
1890    @property
1891    def alias_or_name(self) -> str:
1892        return self.this.alias_or_name
name: str
1886    @property
1887    def name(self) -> str:
1888        return self.this.name
alias_or_name: str
1890    @property
1891    def alias_or_name(self) -> str:
1892        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1895class Having(Expression):
1896    pass
key = 'having'
class Hint(Expression):
1899class Hint(Expression):
1900    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1903class JoinHint(Expression):
1904    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1907class Identifier(Expression):
1908    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1909
1910    @property
1911    def quoted(self) -> bool:
1912        return bool(self.args.get("quoted"))
1913
1914    @property
1915    def hashable_args(self) -> t.Any:
1916        return (self.this, self.quoted)
1917
1918    @property
1919    def output_name(self) -> str:
1920        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1910    @property
1911    def quoted(self) -> bool:
1912        return bool(self.args.get("quoted"))
hashable_args: Any
1914    @property
1915    def hashable_args(self) -> t.Any:
1916        return (self.this, self.quoted)
output_name: str
1918    @property
1919    def output_name(self) -> str:
1920        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):
1924class Opclass(Expression):
1925    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1928class Index(Expression):
1929    arg_types = {
1930        "this": False,
1931        "table": False,
1932        "unique": False,
1933        "primary": False,
1934        "amp": False,  # teradata
1935        "params": False,
1936    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1939class IndexParameters(Expression):
1940    arg_types = {
1941        "using": False,
1942        "include": False,
1943        "columns": False,
1944        "with_storage": False,
1945        "partition_by": False,
1946        "tablespace": False,
1947        "where": False,
1948    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1951class Insert(DDL, DML):
1952    arg_types = {
1953        "hint": False,
1954        "with": False,
1955        "is_function": False,
1956        "this": True,
1957        "expression": False,
1958        "conflict": False,
1959        "returning": False,
1960        "overwrite": False,
1961        "exists": False,
1962        "partition": False,
1963        "alternative": False,
1964        "where": False,
1965        "ignore": False,
1966        "by_name": False,
1967    }
1968
1969    def with_(
1970        self,
1971        alias: ExpOrStr,
1972        as_: ExpOrStr,
1973        recursive: t.Optional[bool] = None,
1974        append: bool = True,
1975        dialect: DialectType = None,
1976        copy: bool = True,
1977        **opts,
1978    ) -> Insert:
1979        """
1980        Append to or set the common table expressions.
1981
1982        Example:
1983            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1984            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1985
1986        Args:
1987            alias: the SQL code string to parse as the table name.
1988                If an `Expression` instance is passed, this is used as-is.
1989            as_: the SQL code string to parse as the table expression.
1990                If an `Expression` instance is passed, it will be used as-is.
1991            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1992            append: if `True`, add to any existing expressions.
1993                Otherwise, this resets the expressions.
1994            dialect: the dialect used to parse the input expression.
1995            copy: if `False`, modify this expression instance in-place.
1996            opts: other options to use to parse the input expressions.
1997
1998        Returns:
1999            The modified expression.
2000        """
2001        return _apply_cte_builder(
2002            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2003        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
1969    def with_(
1970        self,
1971        alias: ExpOrStr,
1972        as_: ExpOrStr,
1973        recursive: t.Optional[bool] = None,
1974        append: bool = True,
1975        dialect: DialectType = None,
1976        copy: bool = True,
1977        **opts,
1978    ) -> Insert:
1979        """
1980        Append to or set the common table expressions.
1981
1982        Example:
1983            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1984            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1985
1986        Args:
1987            alias: the SQL code string to parse as the table name.
1988                If an `Expression` instance is passed, this is used as-is.
1989            as_: the SQL code string to parse as the table expression.
1990                If an `Expression` instance is passed, it will be used as-is.
1991            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1992            append: if `True`, add to any existing expressions.
1993                Otherwise, this resets the expressions.
1994            dialect: the dialect used to parse the input expression.
1995            copy: if `False`, modify this expression instance in-place.
1996            opts: other options to use to parse the input expressions.
1997
1998        Returns:
1999            The modified expression.
2000        """
2001        return _apply_cte_builder(
2002            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2003        )

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):
2006class OnConflict(Expression):
2007    arg_types = {
2008        "duplicate": False,
2009        "expressions": False,
2010        "action": False,
2011        "conflict_keys": False,
2012        "constraint": False,
2013    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2016class Returning(Expression):
2017    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2021class Introducer(Expression):
2022    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2026class National(Expression):
2027    pass
key = 'national'
class LoadData(Expression):
2030class LoadData(Expression):
2031    arg_types = {
2032        "this": True,
2033        "local": False,
2034        "overwrite": False,
2035        "inpath": True,
2036        "partition": False,
2037        "input_format": False,
2038        "serde": False,
2039    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2042class Partition(Expression):
2043    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2046class PartitionRange(Expression):
2047    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2050class Fetch(Expression):
2051    arg_types = {
2052        "direction": False,
2053        "count": False,
2054        "percent": False,
2055        "with_ties": False,
2056    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2059class Group(Expression):
2060    arg_types = {
2061        "expressions": False,
2062        "grouping_sets": False,
2063        "cube": False,
2064        "rollup": False,
2065        "totals": False,
2066        "all": False,
2067    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2070class Lambda(Expression):
2071    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2074class Limit(Expression):
2075    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):
2078class Literal(Condition):
2079    arg_types = {"this": True, "is_string": True}
2080
2081    @property
2082    def hashable_args(self) -> t.Any:
2083        return (self.this, self.args.get("is_string"))
2084
2085    @classmethod
2086    def number(cls, number) -> Literal:
2087        return cls(this=str(number), is_string=False)
2088
2089    @classmethod
2090    def string(cls, string) -> Literal:
2091        return cls(this=str(string), is_string=True)
2092
2093    @property
2094    def output_name(self) -> str:
2095        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2081    @property
2082    def hashable_args(self) -> t.Any:
2083        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2085    @classmethod
2086    def number(cls, number) -> Literal:
2087        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2089    @classmethod
2090    def string(cls, string) -> Literal:
2091        return cls(this=str(string), is_string=True)
output_name: str
2093    @property
2094    def output_name(self) -> str:
2095        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):
2098class Join(Expression):
2099    arg_types = {
2100        "this": True,
2101        "on": False,
2102        "side": False,
2103        "kind": False,
2104        "using": False,
2105        "method": False,
2106        "global": False,
2107        "hint": False,
2108        "match_condition": False,  # Snowflake
2109    }
2110
2111    @property
2112    def method(self) -> str:
2113        return self.text("method").upper()
2114
2115    @property
2116    def kind(self) -> str:
2117        return self.text("kind").upper()
2118
2119    @property
2120    def side(self) -> str:
2121        return self.text("side").upper()
2122
2123    @property
2124    def hint(self) -> str:
2125        return self.text("hint").upper()
2126
2127    @property
2128    def alias_or_name(self) -> str:
2129        return self.this.alias_or_name
2130
2131    def on(
2132        self,
2133        *expressions: t.Optional[ExpOrStr],
2134        append: bool = True,
2135        dialect: DialectType = None,
2136        copy: bool = True,
2137        **opts,
2138    ) -> Join:
2139        """
2140        Append to or set the ON expressions.
2141
2142        Example:
2143            >>> import sqlglot
2144            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2145            'JOIN x ON y = 1'
2146
2147        Args:
2148            *expressions: the SQL code strings to parse.
2149                If an `Expression` instance is passed, it will be used as-is.
2150                Multiple expressions are combined with an AND operator.
2151            append: if `True`, AND the new expressions to any existing expression.
2152                Otherwise, this resets the expression.
2153            dialect: the dialect used to parse the input expressions.
2154            copy: if `False`, modify this expression instance in-place.
2155            opts: other options to use to parse the input expressions.
2156
2157        Returns:
2158            The modified Join expression.
2159        """
2160        join = _apply_conjunction_builder(
2161            *expressions,
2162            instance=self,
2163            arg="on",
2164            append=append,
2165            dialect=dialect,
2166            copy=copy,
2167            **opts,
2168        )
2169
2170        if join.kind == "CROSS":
2171            join.set("kind", None)
2172
2173        return join
2174
2175    def using(
2176        self,
2177        *expressions: t.Optional[ExpOrStr],
2178        append: bool = True,
2179        dialect: DialectType = None,
2180        copy: bool = True,
2181        **opts,
2182    ) -> Join:
2183        """
2184        Append to or set the USING expressions.
2185
2186        Example:
2187            >>> import sqlglot
2188            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2189            'JOIN x USING (foo, bla)'
2190
2191        Args:
2192            *expressions: the SQL code strings to parse.
2193                If an `Expression` instance is passed, it will be used as-is.
2194            append: if `True`, concatenate the new expressions to the existing "using" list.
2195                Otherwise, this resets the expression.
2196            dialect: the dialect used to parse the input expressions.
2197            copy: if `False`, modify this expression instance in-place.
2198            opts: other options to use to parse the input expressions.
2199
2200        Returns:
2201            The modified Join expression.
2202        """
2203        join = _apply_list_builder(
2204            *expressions,
2205            instance=self,
2206            arg="using",
2207            append=append,
2208            dialect=dialect,
2209            copy=copy,
2210            **opts,
2211        )
2212
2213        if join.kind == "CROSS":
2214            join.set("kind", None)
2215
2216        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
2111    @property
2112    def method(self) -> str:
2113        return self.text("method").upper()
kind: str
2115    @property
2116    def kind(self) -> str:
2117        return self.text("kind").upper()
side: str
2119    @property
2120    def side(self) -> str:
2121        return self.text("side").upper()
hint: str
2123    @property
2124    def hint(self) -> str:
2125        return self.text("hint").upper()
alias_or_name: str
2127    @property
2128    def alias_or_name(self) -> str:
2129        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:
2131    def on(
2132        self,
2133        *expressions: t.Optional[ExpOrStr],
2134        append: bool = True,
2135        dialect: DialectType = None,
2136        copy: bool = True,
2137        **opts,
2138    ) -> Join:
2139        """
2140        Append to or set the ON expressions.
2141
2142        Example:
2143            >>> import sqlglot
2144            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2145            'JOIN x ON y = 1'
2146
2147        Args:
2148            *expressions: the SQL code strings to parse.
2149                If an `Expression` instance is passed, it will be used as-is.
2150                Multiple expressions are combined with an AND operator.
2151            append: if `True`, AND the new expressions to any existing expression.
2152                Otherwise, this resets the expression.
2153            dialect: the dialect used to parse the input expressions.
2154            copy: if `False`, modify this expression instance in-place.
2155            opts: other options to use to parse the input expressions.
2156
2157        Returns:
2158            The modified Join expression.
2159        """
2160        join = _apply_conjunction_builder(
2161            *expressions,
2162            instance=self,
2163            arg="on",
2164            append=append,
2165            dialect=dialect,
2166            copy=copy,
2167            **opts,
2168        )
2169
2170        if join.kind == "CROSS":
2171            join.set("kind", None)
2172
2173        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:
2175    def using(
2176        self,
2177        *expressions: t.Optional[ExpOrStr],
2178        append: bool = True,
2179        dialect: DialectType = None,
2180        copy: bool = True,
2181        **opts,
2182    ) -> Join:
2183        """
2184        Append to or set the USING expressions.
2185
2186        Example:
2187            >>> import sqlglot
2188            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2189            'JOIN x USING (foo, bla)'
2190
2191        Args:
2192            *expressions: the SQL code strings to parse.
2193                If an `Expression` instance is passed, it will be used as-is.
2194            append: if `True`, concatenate the new expressions to the existing "using" list.
2195                Otherwise, this resets the expression.
2196            dialect: the dialect used to parse the input expressions.
2197            copy: if `False`, modify this expression instance in-place.
2198            opts: other options to use to parse the input expressions.
2199
2200        Returns:
2201            The modified Join expression.
2202        """
2203        join = _apply_list_builder(
2204            *expressions,
2205            instance=self,
2206            arg="using",
2207            append=append,
2208            dialect=dialect,
2209            copy=copy,
2210            **opts,
2211        )
2212
2213        if join.kind == "CROSS":
2214            join.set("kind", None)
2215
2216        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):
2219class Lateral(UDTF):
2220    arg_types = {
2221        "this": True,
2222        "view": False,
2223        "outer": False,
2224        "alias": False,
2225        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2226    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2229class MatchRecognizeMeasure(Expression):
2230    arg_types = {
2231        "this": True,
2232        "window_frame": False,
2233    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2236class MatchRecognize(Expression):
2237    arg_types = {
2238        "partition_by": False,
2239        "order": False,
2240        "measures": False,
2241        "rows": False,
2242        "after": False,
2243        "pattern": False,
2244        "define": False,
2245        "alias": False,
2246    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2251class Final(Expression):
2252    pass
key = 'final'
class Offset(Expression):
2255class Offset(Expression):
2256    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2259class Order(Expression):
2260    arg_types = {
2261        "this": False,
2262        "expressions": True,
2263        "interpolate": False,
2264        "siblings": False,
2265    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2269class WithFill(Expression):
2270    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2275class Cluster(Order):
2276    pass
key = 'cluster'
class Distribute(Order):
2279class Distribute(Order):
2280    pass
key = 'distribute'
class Sort(Order):
2283class Sort(Order):
2284    pass
key = 'sort'
class Ordered(Expression):
2287class Ordered(Expression):
2288    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):
2291class Property(Expression):
2292    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2295class AlgorithmProperty(Property):
2296    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2299class AutoIncrementProperty(Property):
2300    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2304class AutoRefreshProperty(Property):
2305    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2308class BackupProperty(Property):
2309    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2312class BlockCompressionProperty(Property):
2313    arg_types = {
2314        "autotemp": False,
2315        "always": False,
2316        "default": False,
2317        "manual": False,
2318        "never": False,
2319    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2322class CharacterSetProperty(Property):
2323    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2326class ChecksumProperty(Property):
2327    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2330class CollateProperty(Property):
2331    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2334class CopyGrantsProperty(Property):
2335    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2338class DataBlocksizeProperty(Property):
2339    arg_types = {
2340        "size": False,
2341        "units": False,
2342        "minimum": False,
2343        "maximum": False,
2344        "default": False,
2345    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2348class DefinerProperty(Property):
2349    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2352class DistKeyProperty(Property):
2353    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2356class DistStyleProperty(Property):
2357    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2360class EngineProperty(Property):
2361    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2364class HeapProperty(Property):
2365    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2368class ToTableProperty(Property):
2369    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2372class ExecuteAsProperty(Property):
2373    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2376class ExternalProperty(Property):
2377    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2380class FallbackProperty(Property):
2381    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2384class FileFormatProperty(Property):
2385    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2388class FreespaceProperty(Property):
2389    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2392class GlobalProperty(Property):
2393    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2396class IcebergProperty(Property):
2397    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2400class InheritsProperty(Property):
2401    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2404class InputModelProperty(Property):
2405    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2408class OutputModelProperty(Property):
2409    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2412class IsolatedLoadingProperty(Property):
2413    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2416class JournalProperty(Property):
2417    arg_types = {
2418        "no": False,
2419        "dual": False,
2420        "before": False,
2421        "local": False,
2422        "after": False,
2423    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2426class LanguageProperty(Property):
2427    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2431class ClusteredByProperty(Property):
2432    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2435class DictProperty(Property):
2436    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2439class DictSubProperty(Property):
2440    pass
key = 'dictsubproperty'
class DictRange(Property):
2443class DictRange(Property):
2444    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2449class OnCluster(Property):
2450    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2453class LikeProperty(Property):
2454    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2457class LocationProperty(Property):
2458    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2461class LockProperty(Property):
2462    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2465class LockingProperty(Property):
2466    arg_types = {
2467        "this": False,
2468        "kind": True,
2469        "for_or_in": False,
2470        "lock_type": True,
2471        "override": False,
2472    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2475class LogProperty(Property):
2476    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2479class MaterializedProperty(Property):
2480    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2483class MergeBlockRatioProperty(Property):
2484    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):
2487class NoPrimaryIndexProperty(Property):
2488    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2491class OnProperty(Property):
2492    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2495class OnCommitProperty(Property):
2496    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2499class PartitionedByProperty(Property):
2500    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2504class PartitionBoundSpec(Expression):
2505    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2506    arg_types = {
2507        "this": False,
2508        "expression": False,
2509        "from_expressions": False,
2510        "to_expressions": False,
2511    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2514class PartitionedOfProperty(Property):
2515    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2516    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2519class RemoteWithConnectionModelProperty(Property):
2520    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2523class ReturnsProperty(Property):
2524    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2527class RowFormatProperty(Property):
2528    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2531class RowFormatDelimitedProperty(Property):
2532    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2533    arg_types = {
2534        "fields": False,
2535        "escaped": False,
2536        "collection_items": False,
2537        "map_keys": False,
2538        "lines": False,
2539        "null": False,
2540        "serde": False,
2541    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2544class RowFormatSerdeProperty(Property):
2545    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2549class QueryTransform(Expression):
2550    arg_types = {
2551        "expressions": True,
2552        "command_script": True,
2553        "schema": False,
2554        "row_format_before": False,
2555        "record_writer": False,
2556        "row_format_after": False,
2557        "record_reader": False,
2558    }
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):
2561class SampleProperty(Property):
2562    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2565class SchemaCommentProperty(Property):
2566    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2569class SerdeProperties(Property):
2570    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2573class SetProperty(Property):
2574    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2577class SharingProperty(Property):
2578    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2581class SetConfigProperty(Property):
2582    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2585class SettingsProperty(Property):
2586    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2589class SortKeyProperty(Property):
2590    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2593class SqlReadWriteProperty(Property):
2594    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2597class SqlSecurityProperty(Property):
2598    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2601class StabilityProperty(Property):
2602    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2605class TemporaryProperty(Property):
2606    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2609class TransformModelProperty(Property):
2610    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2613class TransientProperty(Property):
2614    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2617class UnloggedProperty(Property):
2618    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2622class ViewAttributeProperty(Property):
2623    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2626class VolatileProperty(Property):
2627    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2630class WithDataProperty(Property):
2631    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2634class WithJournalTableProperty(Property):
2635    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2638class WithSystemVersioningProperty(Property):
2639    # this -> history table name, expression -> data consistency check
2640    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2643class Properties(Expression):
2644    arg_types = {"expressions": True}
2645
2646    NAME_TO_PROPERTY = {
2647        "ALGORITHM": AlgorithmProperty,
2648        "AUTO_INCREMENT": AutoIncrementProperty,
2649        "CHARACTER SET": CharacterSetProperty,
2650        "CLUSTERED_BY": ClusteredByProperty,
2651        "COLLATE": CollateProperty,
2652        "COMMENT": SchemaCommentProperty,
2653        "DEFINER": DefinerProperty,
2654        "DISTKEY": DistKeyProperty,
2655        "DISTSTYLE": DistStyleProperty,
2656        "ENGINE": EngineProperty,
2657        "EXECUTE AS": ExecuteAsProperty,
2658        "FORMAT": FileFormatProperty,
2659        "LANGUAGE": LanguageProperty,
2660        "LOCATION": LocationProperty,
2661        "LOCK": LockProperty,
2662        "PARTITIONED_BY": PartitionedByProperty,
2663        "RETURNS": ReturnsProperty,
2664        "ROW_FORMAT": RowFormatProperty,
2665        "SORTKEY": SortKeyProperty,
2666    }
2667
2668    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2669
2670    # CREATE property locations
2671    # Form: schema specified
2672    #   create [POST_CREATE]
2673    #     table a [POST_NAME]
2674    #     (b int) [POST_SCHEMA]
2675    #     with ([POST_WITH])
2676    #     index (b) [POST_INDEX]
2677    #
2678    # Form: alias selection
2679    #   create [POST_CREATE]
2680    #     table a [POST_NAME]
2681    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2682    #     index (c) [POST_INDEX]
2683    class Location(AutoName):
2684        POST_CREATE = auto()
2685        POST_NAME = auto()
2686        POST_SCHEMA = auto()
2687        POST_WITH = auto()
2688        POST_ALIAS = auto()
2689        POST_EXPRESSION = auto()
2690        POST_INDEX = auto()
2691        UNSUPPORTED = auto()
2692
2693    @classmethod
2694    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2695        expressions = []
2696        for key, value in properties_dict.items():
2697            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2698            if property_cls:
2699                expressions.append(property_cls(this=convert(value)))
2700            else:
2701                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2702
2703        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:
2693    @classmethod
2694    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2695        expressions = []
2696        for key, value in properties_dict.items():
2697            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2698            if property_cls:
2699                expressions.append(property_cls(this=convert(value)))
2700            else:
2701                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2702
2703        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2683    class Location(AutoName):
2684        POST_CREATE = auto()
2685        POST_NAME = auto()
2686        POST_SCHEMA = auto()
2687        POST_WITH = auto()
2688        POST_ALIAS = auto()
2689        POST_EXPRESSION = auto()
2690        POST_INDEX = auto()
2691        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):
2706class Qualify(Expression):
2707    pass
key = 'qualify'
class InputOutputFormat(Expression):
2710class InputOutputFormat(Expression):
2711    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2715class Return(Expression):
2716    pass
key = 'return'
class Reference(Expression):
2719class Reference(Expression):
2720    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2723class Tuple(Expression):
2724    arg_types = {"expressions": False}
2725
2726    def isin(
2727        self,
2728        *expressions: t.Any,
2729        query: t.Optional[ExpOrStr] = None,
2730        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2731        copy: bool = True,
2732        **opts,
2733    ) -> In:
2734        return In(
2735            this=maybe_copy(self, copy),
2736            expressions=[convert(e, copy=copy) for e in expressions],
2737            query=maybe_parse(query, copy=copy, **opts) if query else None,
2738            unnest=(
2739                Unnest(
2740                    expressions=[
2741                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2742                        for e in ensure_list(unnest)
2743                    ]
2744                )
2745                if unnest
2746                else None
2747            ),
2748        )
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:
2726    def isin(
2727        self,
2728        *expressions: t.Any,
2729        query: t.Optional[ExpOrStr] = None,
2730        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2731        copy: bool = True,
2732        **opts,
2733    ) -> In:
2734        return In(
2735            this=maybe_copy(self, copy),
2736            expressions=[convert(e, copy=copy) for e in expressions],
2737            query=maybe_parse(query, copy=copy, **opts) if query else None,
2738            unnest=(
2739                Unnest(
2740                    expressions=[
2741                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2742                        for e in ensure_list(unnest)
2743                    ]
2744                )
2745                if unnest
2746                else None
2747            ),
2748        )
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):
2779class QueryOption(Expression):
2780    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2784class WithTableHint(Expression):
2785    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2789class IndexTableHint(Expression):
2790    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2794class HistoricalData(Expression):
2795    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2798class Table(Expression):
2799    arg_types = {
2800        "this": False,
2801        "alias": False,
2802        "db": False,
2803        "catalog": False,
2804        "laterals": False,
2805        "joins": False,
2806        "pivots": False,
2807        "hints": False,
2808        "system_time": False,
2809        "version": False,
2810        "format": False,
2811        "pattern": False,
2812        "ordinality": False,
2813        "when": False,
2814        "only": False,
2815    }
2816
2817    @property
2818    def name(self) -> str:
2819        if isinstance(self.this, Func):
2820            return ""
2821        return self.this.name
2822
2823    @property
2824    def db(self) -> str:
2825        return self.text("db")
2826
2827    @property
2828    def catalog(self) -> str:
2829        return self.text("catalog")
2830
2831    @property
2832    def selects(self) -> t.List[Expression]:
2833        return []
2834
2835    @property
2836    def named_selects(self) -> t.List[str]:
2837        return []
2838
2839    @property
2840    def parts(self) -> t.List[Expression]:
2841        """Return the parts of a table in order catalog, db, table."""
2842        parts: t.List[Expression] = []
2843
2844        for arg in ("catalog", "db", "this"):
2845            part = self.args.get(arg)
2846
2847            if isinstance(part, Dot):
2848                parts.extend(part.flatten())
2849            elif isinstance(part, Expression):
2850                parts.append(part)
2851
2852        return parts
2853
2854    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2855        parts = self.parts
2856        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2857        alias = self.args.get("alias")
2858        if alias:
2859            col = alias_(col, alias.this, copy=copy)
2860        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False}
name: str
2817    @property
2818    def name(self) -> str:
2819        if isinstance(self.this, Func):
2820            return ""
2821        return self.this.name
db: str
2823    @property
2824    def db(self) -> str:
2825        return self.text("db")
catalog: str
2827    @property
2828    def catalog(self) -> str:
2829        return self.text("catalog")
selects: List[Expression]
2831    @property
2832    def selects(self) -> t.List[Expression]:
2833        return []
named_selects: List[str]
2835    @property
2836    def named_selects(self) -> t.List[str]:
2837        return []
parts: List[Expression]
2839    @property
2840    def parts(self) -> t.List[Expression]:
2841        """Return the parts of a table in order catalog, db, table."""
2842        parts: t.List[Expression] = []
2843
2844        for arg in ("catalog", "db", "this"):
2845            part = self.args.get(arg)
2846
2847            if isinstance(part, Dot):
2848                parts.extend(part.flatten())
2849            elif isinstance(part, Expression):
2850                parts.append(part)
2851
2852        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2854    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2855        parts = self.parts
2856        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2857        alias = self.args.get("alias")
2858        if alias:
2859            col = alias_(col, alias.this, copy=copy)
2860        return col
key = 'table'
class Union(Query):
2863class Union(Query):
2864    arg_types = {
2865        "with": False,
2866        "this": True,
2867        "expression": True,
2868        "distinct": False,
2869        "by_name": False,
2870        **QUERY_MODIFIERS,
2871    }
2872
2873    def select(
2874        self,
2875        *expressions: t.Optional[ExpOrStr],
2876        append: bool = True,
2877        dialect: DialectType = None,
2878        copy: bool = True,
2879        **opts,
2880    ) -> Union:
2881        this = maybe_copy(self, copy)
2882        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2883        this.expression.unnest().select(
2884            *expressions, append=append, dialect=dialect, copy=False, **opts
2885        )
2886        return this
2887
2888    @property
2889    def named_selects(self) -> t.List[str]:
2890        return self.this.unnest().named_selects
2891
2892    @property
2893    def is_star(self) -> bool:
2894        return self.this.is_star or self.expression.is_star
2895
2896    @property
2897    def selects(self) -> t.List[Expression]:
2898        return self.this.unnest().selects
2899
2900    @property
2901    def left(self) -> Expression:
2902        return self.this
2903
2904    @property
2905    def right(self) -> Expression:
2906        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:
2873    def select(
2874        self,
2875        *expressions: t.Optional[ExpOrStr],
2876        append: bool = True,
2877        dialect: DialectType = None,
2878        copy: bool = True,
2879        **opts,
2880    ) -> Union:
2881        this = maybe_copy(self, copy)
2882        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2883        this.expression.unnest().select(
2884            *expressions, append=append, dialect=dialect, copy=False, **opts
2885        )
2886        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]
2888    @property
2889    def named_selects(self) -> t.List[str]:
2890        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2892    @property
2893    def is_star(self) -> bool:
2894        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2896    @property
2897    def selects(self) -> t.List[Expression]:
2898        return self.this.unnest().selects

Returns the query's projections.

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

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

Set the GROUP BY expression.

Example:
>>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
'SELECT x, COUNT(1) FROM tbl GROUP BY x'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Group. If nothing is passed in then a group by is not applied to the expression
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Group expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

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

Set the ORDER BY expression.

Example:
>>> Select().from_("tbl").select("x").order_by("x DESC").sql()
'SELECT x FROM tbl ORDER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Order.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3106    def sort_by(
3107        self,
3108        *expressions: t.Optional[ExpOrStr],
3109        append: bool = True,
3110        dialect: DialectType = None,
3111        copy: bool = True,
3112        **opts,
3113    ) -> Select:
3114        """
3115        Set the SORT BY expression.
3116
3117        Example:
3118            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3119            'SELECT x FROM tbl SORT BY x DESC'
3120
3121        Args:
3122            *expressions: the SQL code strings to parse.
3123                If a `Group` instance is passed, this is used as-is.
3124                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3125            append: if `True`, add to any existing expressions.
3126                Otherwise, this flattens all the `Order` expression into a single expression.
3127            dialect: the dialect used to parse the input expression.
3128            copy: if `False`, modify this expression instance in-place.
3129            opts: other options to use to parse the input expressions.
3130
3131        Returns:
3132            The modified Select expression.
3133        """
3134        return _apply_child_list_builder(
3135            *expressions,
3136            instance=self,
3137            arg="sort",
3138            append=append,
3139            copy=copy,
3140            prefix="SORT BY",
3141            into=Sort,
3142            dialect=dialect,
3143            **opts,
3144        )

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:
3146    def cluster_by(
3147        self,
3148        *expressions: t.Optional[ExpOrStr],
3149        append: bool = True,
3150        dialect: DialectType = None,
3151        copy: bool = True,
3152        **opts,
3153    ) -> Select:
3154        """
3155        Set the CLUSTER BY expression.
3156
3157        Example:
3158            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3159            'SELECT x FROM tbl CLUSTER BY x DESC'
3160
3161        Args:
3162            *expressions: the SQL code strings to parse.
3163                If a `Group` instance is passed, this is used as-is.
3164                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3165            append: if `True`, add to any existing expressions.
3166                Otherwise, this flattens all the `Order` expression into a single expression.
3167            dialect: the dialect used to parse the input expression.
3168            copy: if `False`, modify this expression instance in-place.
3169            opts: other options to use to parse the input expressions.
3170
3171        Returns:
3172            The modified Select expression.
3173        """
3174        return _apply_child_list_builder(
3175            *expressions,
3176            instance=self,
3177            arg="cluster",
3178            append=append,
3179            copy=copy,
3180            prefix="CLUSTER BY",
3181            into=Cluster,
3182            dialect=dialect,
3183            **opts,
3184        )

Set the CLUSTER BY expression.

Example:
>>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
'SELECT x FROM tbl CLUSTER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Cluster.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3186    def limit(
3187        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3188    ) -> Select:
3189        return _apply_builder(
3190            expression=expression,
3191            instance=self,
3192            arg="limit",
3193            into=Limit,
3194            prefix="LIMIT",
3195            dialect=dialect,
3196            copy=copy,
3197            into_arg="expression",
3198            **opts,
3199        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

def offset( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3201    def offset(
3202        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3203    ) -> Select:
3204        """
3205        Set the OFFSET expression.
3206
3207        Example:
3208            >>> Select().from_("tbl").select("x").offset(10).sql()
3209            'SELECT x FROM tbl OFFSET 10'
3210
3211        Args:
3212            expression: the SQL code string to parse.
3213                This can also be an integer.
3214                If a `Offset` instance is passed, this is used as-is.
3215                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3216            dialect: the dialect used to parse the input expression.
3217            copy: if `False`, modify this expression instance in-place.
3218            opts: other options to use to parse the input expressions.
3219
3220        Returns:
3221            The modified Select expression.
3222        """
3223        return _apply_builder(
3224            expression=expression,
3225            instance=self,
3226            arg="offset",
3227            into=Offset,
3228            prefix="OFFSET",
3229            dialect=dialect,
3230            copy=copy,
3231            into_arg="expression",
3232            **opts,
3233        )

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").offset(10).sql()
'SELECT x FROM tbl OFFSET 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Offset instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Offset.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3235    def select(
3236        self,
3237        *expressions: t.Optional[ExpOrStr],
3238        append: bool = True,
3239        dialect: DialectType = None,
3240        copy: bool = True,
3241        **opts,
3242    ) -> Select:
3243        return _apply_list_builder(
3244            *expressions,
3245            instance=self,
3246            arg="expressions",
3247            append=append,
3248            dialect=dialect,
3249            into=Expression,
3250            copy=copy,
3251            **opts,
3252        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3625    @property
3626    def selects(self) -> t.List[Expression]:
3627        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3648    def unwrap(self) -> Subquery:
3649        expression = self
3650        while expression.same_parent and expression.is_wrapper:
3651            expression = t.cast(Subquery, expression.parent)
3652        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:
3654    def select(
3655        self,
3656        *expressions: t.Optional[ExpOrStr],
3657        append: bool = True,
3658        dialect: DialectType = None,
3659        copy: bool = True,
3660        **opts,
3661    ) -> Subquery:
3662        this = maybe_copy(self, copy)
3663        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3664        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
3666    @property
3667    def is_wrapper(self) -> bool:
3668        """
3669        Whether this Subquery acts as a simple wrapper around another expression.
3670
3671        SELECT * FROM (((SELECT * FROM t)))
3672                      ^
3673                      This corresponds to a "wrapper" Subquery node
3674        """
3675        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
3677    @property
3678    def is_star(self) -> bool:
3679        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3681    @property
3682    def output_name(self) -> str:
3683        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):
3686class TableSample(Expression):
3687    arg_types = {
3688        "this": False,
3689        "expressions": False,
3690        "method": False,
3691        "bucket_numerator": False,
3692        "bucket_denominator": False,
3693        "bucket_field": False,
3694        "percent": False,
3695        "rows": False,
3696        "size": False,
3697        "seed": False,
3698    }
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):
3701class Tag(Expression):
3702    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3703
3704    arg_types = {
3705        "this": False,
3706        "prefix": False,
3707        "postfix": False,
3708    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3713class Pivot(Expression):
3714    arg_types = {
3715        "this": False,
3716        "alias": False,
3717        "expressions": False,
3718        "field": False,
3719        "unpivot": False,
3720        "using": False,
3721        "group": False,
3722        "columns": False,
3723        "include_nulls": False,
3724    }
3725
3726    @property
3727    def unpivot(self) -> bool:
3728        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
3726    @property
3727    def unpivot(self) -> bool:
3728        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3731class Window(Condition):
3732    arg_types = {
3733        "this": True,
3734        "partition_by": False,
3735        "order": False,
3736        "spec": False,
3737        "alias": False,
3738        "over": False,
3739        "first": False,
3740    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3743class WindowSpec(Expression):
3744    arg_types = {
3745        "kind": False,
3746        "start": False,
3747        "start_side": False,
3748        "end": False,
3749        "end_side": False,
3750    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3753class PreWhere(Expression):
3754    pass
key = 'prewhere'
class Where(Expression):
3757class Where(Expression):
3758    pass
key = 'where'
class Star(Expression):
3761class Star(Expression):
3762    arg_types = {"except": False, "replace": False}
3763
3764    @property
3765    def name(self) -> str:
3766        return "*"
3767
3768    @property
3769    def output_name(self) -> str:
3770        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3764    @property
3765    def name(self) -> str:
3766        return "*"
output_name: str
3768    @property
3769    def output_name(self) -> str:
3770        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):
3773class Parameter(Condition):
3774    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3777class SessionParameter(Condition):
3778    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3781class Placeholder(Condition):
3782    arg_types = {"this": False, "kind": False}
3783
3784    @property
3785    def name(self) -> str:
3786        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3784    @property
3785    def name(self) -> str:
3786        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3789class Null(Condition):
3790    arg_types: t.Dict[str, t.Any] = {}
3791
3792    @property
3793    def name(self) -> str:
3794        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3792    @property
3793    def name(self) -> str:
3794        return "NULL"
key = 'null'
class Boolean(Condition):
3797class Boolean(Condition):
3798    pass
key = 'boolean'
class DataTypeParam(Expression):
3801class DataTypeParam(Expression):
3802    arg_types = {"this": True, "expression": False}
3803
3804    @property
3805    def name(self) -> str:
3806        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3804    @property
3805    def name(self) -> str:
3806        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3809class DataType(Expression):
3810    arg_types = {
3811        "this": True,
3812        "expressions": False,
3813        "nested": False,
3814        "values": False,
3815        "prefix": False,
3816        "kind": False,
3817    }
3818
3819    class Type(AutoName):
3820        ARRAY = auto()
3821        AGGREGATEFUNCTION = auto()
3822        SIMPLEAGGREGATEFUNCTION = auto()
3823        BIGDECIMAL = auto()
3824        BIGINT = auto()
3825        BIGSERIAL = auto()
3826        BINARY = auto()
3827        BIT = auto()
3828        BOOLEAN = auto()
3829        BPCHAR = auto()
3830        CHAR = auto()
3831        DATE = auto()
3832        DATE32 = auto()
3833        DATEMULTIRANGE = auto()
3834        DATERANGE = auto()
3835        DATETIME = auto()
3836        DATETIME64 = auto()
3837        DECIMAL = auto()
3838        DOUBLE = auto()
3839        ENUM = auto()
3840        ENUM8 = auto()
3841        ENUM16 = auto()
3842        FIXEDSTRING = auto()
3843        FLOAT = auto()
3844        GEOGRAPHY = auto()
3845        GEOMETRY = auto()
3846        HLLSKETCH = auto()
3847        HSTORE = auto()
3848        IMAGE = auto()
3849        INET = auto()
3850        INT = auto()
3851        INT128 = auto()
3852        INT256 = auto()
3853        INT4MULTIRANGE = auto()
3854        INT4RANGE = auto()
3855        INT8MULTIRANGE = auto()
3856        INT8RANGE = auto()
3857        INTERVAL = auto()
3858        IPADDRESS = auto()
3859        IPPREFIX = auto()
3860        IPV4 = auto()
3861        IPV6 = auto()
3862        JSON = auto()
3863        JSONB = auto()
3864        LONGBLOB = auto()
3865        LONGTEXT = auto()
3866        LOWCARDINALITY = auto()
3867        MAP = auto()
3868        MEDIUMBLOB = auto()
3869        MEDIUMINT = auto()
3870        MEDIUMTEXT = auto()
3871        MONEY = auto()
3872        NAME = auto()
3873        NCHAR = auto()
3874        NESTED = auto()
3875        NULL = auto()
3876        NULLABLE = auto()
3877        NUMMULTIRANGE = auto()
3878        NUMRANGE = auto()
3879        NVARCHAR = auto()
3880        OBJECT = auto()
3881        ROWVERSION = auto()
3882        SERIAL = auto()
3883        SET = auto()
3884        SMALLINT = auto()
3885        SMALLMONEY = auto()
3886        SMALLSERIAL = auto()
3887        STRUCT = auto()
3888        SUPER = auto()
3889        TEXT = auto()
3890        TINYBLOB = auto()
3891        TINYTEXT = auto()
3892        TIME = auto()
3893        TIMETZ = auto()
3894        TIMESTAMP = auto()
3895        TIMESTAMPLTZ = auto()
3896        TIMESTAMPTZ = auto()
3897        TIMESTAMP_S = auto()
3898        TIMESTAMP_MS = auto()
3899        TIMESTAMP_NS = auto()
3900        TINYINT = auto()
3901        TSMULTIRANGE = auto()
3902        TSRANGE = auto()
3903        TSTZMULTIRANGE = auto()
3904        TSTZRANGE = auto()
3905        UBIGINT = auto()
3906        UINT = auto()
3907        UINT128 = auto()
3908        UINT256 = auto()
3909        UMEDIUMINT = auto()
3910        UDECIMAL = auto()
3911        UNIQUEIDENTIFIER = auto()
3912        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3913        USERDEFINED = "USER-DEFINED"
3914        USMALLINT = auto()
3915        UTINYINT = auto()
3916        UUID = auto()
3917        VARBINARY = auto()
3918        VARCHAR = auto()
3919        VARIANT = auto()
3920        XML = auto()
3921        YEAR = auto()
3922
3923    STRUCT_TYPES = {
3924        Type.NESTED,
3925        Type.OBJECT,
3926        Type.STRUCT,
3927    }
3928
3929    NESTED_TYPES = {
3930        *STRUCT_TYPES,
3931        Type.ARRAY,
3932        Type.MAP,
3933    }
3934
3935    TEXT_TYPES = {
3936        Type.CHAR,
3937        Type.NCHAR,
3938        Type.NVARCHAR,
3939        Type.TEXT,
3940        Type.VARCHAR,
3941        Type.NAME,
3942    }
3943
3944    SIGNED_INTEGER_TYPES = {
3945        Type.BIGINT,
3946        Type.INT,
3947        Type.INT128,
3948        Type.INT256,
3949        Type.MEDIUMINT,
3950        Type.SMALLINT,
3951        Type.TINYINT,
3952    }
3953
3954    UNSIGNED_INTEGER_TYPES = {
3955        Type.UBIGINT,
3956        Type.UINT,
3957        Type.UINT128,
3958        Type.UINT256,
3959        Type.UMEDIUMINT,
3960        Type.USMALLINT,
3961        Type.UTINYINT,
3962    }
3963
3964    INTEGER_TYPES = {
3965        *SIGNED_INTEGER_TYPES,
3966        *UNSIGNED_INTEGER_TYPES,
3967        Type.BIT,
3968    }
3969
3970    FLOAT_TYPES = {
3971        Type.DOUBLE,
3972        Type.FLOAT,
3973    }
3974
3975    REAL_TYPES = {
3976        *FLOAT_TYPES,
3977        Type.BIGDECIMAL,
3978        Type.DECIMAL,
3979        Type.MONEY,
3980        Type.SMALLMONEY,
3981        Type.UDECIMAL,
3982    }
3983
3984    NUMERIC_TYPES = {
3985        *INTEGER_TYPES,
3986        *REAL_TYPES,
3987    }
3988
3989    TEMPORAL_TYPES = {
3990        Type.DATE,
3991        Type.DATE32,
3992        Type.DATETIME,
3993        Type.DATETIME64,
3994        Type.TIME,
3995        Type.TIMESTAMP,
3996        Type.TIMESTAMPLTZ,
3997        Type.TIMESTAMPTZ,
3998        Type.TIMESTAMP_MS,
3999        Type.TIMESTAMP_NS,
4000        Type.TIMESTAMP_S,
4001        Type.TIMETZ,
4002    }
4003
4004    @classmethod
4005    def build(
4006        cls,
4007        dtype: DATA_TYPE,
4008        dialect: DialectType = None,
4009        udt: bool = False,
4010        copy: bool = True,
4011        **kwargs,
4012    ) -> DataType:
4013        """
4014        Constructs a DataType object.
4015
4016        Args:
4017            dtype: the data type of interest.
4018            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4019            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4020                DataType, thus creating a user-defined type.
4021            copy: whether to copy the data type.
4022            kwargs: additional arguments to pass in the constructor of DataType.
4023
4024        Returns:
4025            The constructed DataType object.
4026        """
4027        from sqlglot import parse_one
4028
4029        if isinstance(dtype, str):
4030            if dtype.upper() == "UNKNOWN":
4031                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4032
4033            try:
4034                data_type_exp = parse_one(
4035                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4036                )
4037            except ParseError:
4038                if udt:
4039                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4040                raise
4041        elif isinstance(dtype, DataType.Type):
4042            data_type_exp = DataType(this=dtype)
4043        elif isinstance(dtype, DataType):
4044            return maybe_copy(dtype, copy)
4045        else:
4046            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4047
4048        return DataType(**{**data_type_exp.args, **kwargs})
4049
4050    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4051        """
4052        Checks whether this DataType matches one of the provided data types. Nested types or precision
4053        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4054
4055        Args:
4056            dtypes: the data types to compare this DataType to.
4057
4058        Returns:
4059            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4060        """
4061        for dtype in dtypes:
4062            other = DataType.build(dtype, copy=False, udt=True)
4063
4064            if (
4065                other.expressions
4066                or self.this == DataType.Type.USERDEFINED
4067                or other.this == DataType.Type.USERDEFINED
4068            ):
4069                matches = self == other
4070            else:
4071                matches = self.this == other.this
4072
4073            if matches:
4074                return True
4075        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.MAP: 'MAP'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>}
NUMERIC_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT: 'INT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.FLOAT: 'FLOAT'>, <Type.UINT256: 'UINT256'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.MONEY: 'MONEY'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT128: 'UINT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>}
TEMPORAL_TYPES = {<Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4004    @classmethod
4005    def build(
4006        cls,
4007        dtype: DATA_TYPE,
4008        dialect: DialectType = None,
4009        udt: bool = False,
4010        copy: bool = True,
4011        **kwargs,
4012    ) -> DataType:
4013        """
4014        Constructs a DataType object.
4015
4016        Args:
4017            dtype: the data type of interest.
4018            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4019            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4020                DataType, thus creating a user-defined type.
4021            copy: whether to copy the data type.
4022            kwargs: additional arguments to pass in the constructor of DataType.
4023
4024        Returns:
4025            The constructed DataType object.
4026        """
4027        from sqlglot import parse_one
4028
4029        if isinstance(dtype, str):
4030            if dtype.upper() == "UNKNOWN":
4031                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4032
4033            try:
4034                data_type_exp = parse_one(
4035                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4036                )
4037            except ParseError:
4038                if udt:
4039                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4040                raise
4041        elif isinstance(dtype, DataType.Type):
4042            data_type_exp = DataType(this=dtype)
4043        elif isinstance(dtype, DataType):
4044            return maybe_copy(dtype, copy)
4045        else:
4046            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4047
4048        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:
4050    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4051        """
4052        Checks whether this DataType matches one of the provided data types. Nested types or precision
4053        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4054
4055        Args:
4056            dtypes: the data types to compare this DataType to.
4057
4058        Returns:
4059            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4060        """
4061        for dtype in dtypes:
4062            other = DataType.build(dtype, copy=False, udt=True)
4063
4064            if (
4065                other.expressions
4066                or self.this == DataType.Type.USERDEFINED
4067                or other.this == DataType.Type.USERDEFINED
4068            ):
4069                matches = self == other
4070            else:
4071                matches = self.this == other.this
4072
4073            if matches:
4074                return True
4075        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):
3819    class Type(AutoName):
3820        ARRAY = auto()
3821        AGGREGATEFUNCTION = auto()
3822        SIMPLEAGGREGATEFUNCTION = auto()
3823        BIGDECIMAL = auto()
3824        BIGINT = auto()
3825        BIGSERIAL = auto()
3826        BINARY = auto()
3827        BIT = auto()
3828        BOOLEAN = auto()
3829        BPCHAR = auto()
3830        CHAR = auto()
3831        DATE = auto()
3832        DATE32 = auto()
3833        DATEMULTIRANGE = auto()
3834        DATERANGE = auto()
3835        DATETIME = auto()
3836        DATETIME64 = auto()
3837        DECIMAL = auto()
3838        DOUBLE = auto()
3839        ENUM = auto()
3840        ENUM8 = auto()
3841        ENUM16 = auto()
3842        FIXEDSTRING = auto()
3843        FLOAT = auto()
3844        GEOGRAPHY = auto()
3845        GEOMETRY = auto()
3846        HLLSKETCH = auto()
3847        HSTORE = auto()
3848        IMAGE = auto()
3849        INET = auto()
3850        INT = auto()
3851        INT128 = auto()
3852        INT256 = auto()
3853        INT4MULTIRANGE = auto()
3854        INT4RANGE = auto()
3855        INT8MULTIRANGE = auto()
3856        INT8RANGE = auto()
3857        INTERVAL = auto()
3858        IPADDRESS = auto()
3859        IPPREFIX = auto()
3860        IPV4 = auto()
3861        IPV6 = auto()
3862        JSON = auto()
3863        JSONB = auto()
3864        LONGBLOB = auto()
3865        LONGTEXT = auto()
3866        LOWCARDINALITY = auto()
3867        MAP = auto()
3868        MEDIUMBLOB = auto()
3869        MEDIUMINT = auto()
3870        MEDIUMTEXT = auto()
3871        MONEY = auto()
3872        NAME = auto()
3873        NCHAR = auto()
3874        NESTED = auto()
3875        NULL = auto()
3876        NULLABLE = auto()
3877        NUMMULTIRANGE = auto()
3878        NUMRANGE = auto()
3879        NVARCHAR = auto()
3880        OBJECT = auto()
3881        ROWVERSION = auto()
3882        SERIAL = auto()
3883        SET = auto()
3884        SMALLINT = auto()
3885        SMALLMONEY = auto()
3886        SMALLSERIAL = auto()
3887        STRUCT = auto()
3888        SUPER = auto()
3889        TEXT = auto()
3890        TINYBLOB = auto()
3891        TINYTEXT = auto()
3892        TIME = auto()
3893        TIMETZ = auto()
3894        TIMESTAMP = auto()
3895        TIMESTAMPLTZ = auto()
3896        TIMESTAMPTZ = auto()
3897        TIMESTAMP_S = auto()
3898        TIMESTAMP_MS = auto()
3899        TIMESTAMP_NS = auto()
3900        TINYINT = auto()
3901        TSMULTIRANGE = auto()
3902        TSRANGE = auto()
3903        TSTZMULTIRANGE = auto()
3904        TSTZRANGE = auto()
3905        UBIGINT = auto()
3906        UINT = auto()
3907        UINT128 = auto()
3908        UINT256 = auto()
3909        UMEDIUMINT = auto()
3910        UDECIMAL = auto()
3911        UNIQUEIDENTIFIER = auto()
3912        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3913        USERDEFINED = "USER-DEFINED"
3914        USMALLINT = auto()
3915        UTINYINT = auto()
3916        UUID = auto()
3917        VARBINARY = auto()
3918        VARCHAR = auto()
3919        VARIANT = auto()
3920        XML = auto()
3921        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):
4082class PseudoType(DataType):
4083    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4087class ObjectIdentifier(DataType):
4088    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4092class SubqueryPredicate(Predicate):
4093    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4096class All(SubqueryPredicate):
4097    pass
key = 'all'
class Any(SubqueryPredicate):
4100class Any(SubqueryPredicate):
4101    pass
key = 'any'
class Exists(SubqueryPredicate):
4104class Exists(SubqueryPredicate):
4105    pass
key = 'exists'
class Command(Expression):
4110class Command(Expression):
4111    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4114class Transaction(Expression):
4115    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4118class Commit(Expression):
4119    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4122class Rollback(Expression):
4123    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4126class AlterTable(Expression):
4127    arg_types = {
4128        "this": True,
4129        "actions": True,
4130        "exists": False,
4131        "only": False,
4132        "options": False,
4133    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False}
key = 'altertable'
class AddConstraint(Expression):
4136class AddConstraint(Expression):
4137    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4140class DropPartition(Expression):
4141    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
4145class Binary(Condition):
4146    arg_types = {"this": True, "expression": True}
4147
4148    @property
4149    def left(self) -> Expression:
4150        return self.this
4151
4152    @property
4153    def right(self) -> Expression:
4154        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4148    @property
4149    def left(self) -> Expression:
4150        return self.this
right: Expression
4152    @property
4153    def right(self) -> Expression:
4154        return self.expression
key = 'binary'
class Add(Binary):
4157class Add(Binary):
4158    pass
key = 'add'
class Connector(Binary):
4161class Connector(Binary):
4162    pass
key = 'connector'
class And(Connector):
4165class And(Connector):
4166    pass
key = 'and'
class Or(Connector):
4169class Or(Connector):
4170    pass
key = 'or'
class BitwiseAnd(Binary):
4173class BitwiseAnd(Binary):
4174    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4177class BitwiseLeftShift(Binary):
4178    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4181class BitwiseOr(Binary):
4182    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4185class BitwiseRightShift(Binary):
4186    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4189class BitwiseXor(Binary):
4190    pass
key = 'bitwisexor'
class Div(Binary):
4193class Div(Binary):
4194    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):
4197class Overlaps(Binary):
4198    pass
key = 'overlaps'
class Dot(Binary):
4201class Dot(Binary):
4202    @property
4203    def is_star(self) -> bool:
4204        return self.expression.is_star
4205
4206    @property
4207    def name(self) -> str:
4208        return self.expression.name
4209
4210    @property
4211    def output_name(self) -> str:
4212        return self.name
4213
4214    @classmethod
4215    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4216        """Build a Dot object with a sequence of expressions."""
4217        if len(expressions) < 2:
4218            raise ValueError("Dot requires >= 2 expressions.")
4219
4220        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4221
4222    @property
4223    def parts(self) -> t.List[Expression]:
4224        """Return the parts of a table / column in order catalog, db, table."""
4225        this, *parts = self.flatten()
4226
4227        parts.reverse()
4228
4229        for arg in ("this", "table", "db", "catalog"):
4230            part = this.args.get(arg)
4231
4232            if isinstance(part, Expression):
4233                parts.append(part)
4234
4235        parts.reverse()
4236        return parts
is_star: bool
4202    @property
4203    def is_star(self) -> bool:
4204        return self.expression.is_star

Checks whether an expression is a star.

name: str
4206    @property
4207    def name(self) -> str:
4208        return self.expression.name
output_name: str
4210    @property
4211    def output_name(self) -> str:
4212        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:
4214    @classmethod
4215    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4216        """Build a Dot object with a sequence of expressions."""
4217        if len(expressions) < 2:
4218            raise ValueError("Dot requires >= 2 expressions.")
4219
4220        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]
4222    @property
4223    def parts(self) -> t.List[Expression]:
4224        """Return the parts of a table / column in order catalog, db, table."""
4225        this, *parts = self.flatten()
4226
4227        parts.reverse()
4228
4229        for arg in ("this", "table", "db", "catalog"):
4230            part = this.args.get(arg)
4231
4232            if isinstance(part, Expression):
4233                parts.append(part)
4234
4235        parts.reverse()
4236        return parts

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
4300class Like(Binary, Predicate):
4301    pass
key = 'like'
class LikeAny(Binary, Predicate):
4304class LikeAny(Binary, Predicate):
4305    pass
key = 'likeany'
class LT(Binary, Predicate):
4308class LT(Binary, Predicate):
4309    pass
key = 'lt'
class LTE(Binary, Predicate):
4312class LTE(Binary, Predicate):
4313    pass
key = 'lte'
class Mod(Binary):
4316class Mod(Binary):
4317    pass
key = 'mod'
class Mul(Binary):
4320class Mul(Binary):
4321    pass
key = 'mul'
class NEQ(Binary, Predicate):
4324class NEQ(Binary, Predicate):
4325    pass
key = 'neq'
class Operator(Binary):
4329class Operator(Binary):
4330    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4333class SimilarTo(Binary, Predicate):
4334    pass
key = 'similarto'
class Slice(Binary):
4337class Slice(Binary):
4338    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4341class Sub(Binary):
4342    pass
key = 'sub'
class Unary(Condition):
4347class Unary(Condition):
4348    pass
key = 'unary'
class BitwiseNot(Unary):
4351class BitwiseNot(Unary):
4352    pass
key = 'bitwisenot'
class Not(Unary):
4355class Not(Unary):
4356    pass
key = 'not'
class Paren(Unary):
4359class Paren(Unary):
4360    @property
4361    def output_name(self) -> str:
4362        return self.this.name
output_name: str
4360    @property
4361    def output_name(self) -> str:
4362        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):
4365class Neg(Unary):
4366    pass
key = 'neg'
class Alias(Expression):
4369class Alias(Expression):
4370    arg_types = {"this": True, "alias": False}
4371
4372    @property
4373    def output_name(self) -> str:
4374        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4372    @property
4373    def output_name(self) -> str:
4374        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):
4379class PivotAlias(Alias):
4380    pass
key = 'pivotalias'
class Aliases(Expression):
4383class Aliases(Expression):
4384    arg_types = {"this": True, "expressions": True}
4385
4386    @property
4387    def aliases(self):
4388        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4386    @property
4387    def aliases(self):
4388        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4392class AtIndex(Expression):
4393    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4396class AtTimeZone(Expression):
4397    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4400class FromTimeZone(Expression):
4401    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4404class Between(Predicate):
4405    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4408class Bracket(Condition):
4409    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4410    arg_types = {
4411        "this": True,
4412        "expressions": True,
4413        "offset": False,
4414        "safe": False,
4415        "returns_list_for_maps": False,
4416    }
4417
4418    @property
4419    def output_name(self) -> str:
4420        if len(self.expressions) == 1:
4421            return self.expressions[0].output_name
4422
4423        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4418    @property
4419    def output_name(self) -> str:
4420        if len(self.expressions) == 1:
4421            return self.expressions[0].output_name
4422
4423        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):
4426class Distinct(Expression):
4427    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4430class In(Predicate):
4431    arg_types = {
4432        "this": True,
4433        "expressions": False,
4434        "query": False,
4435        "unnest": False,
4436        "field": False,
4437        "is_global": False,
4438    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4442class ForIn(Expression):
4443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4446class TimeUnit(Expression):
4447    """Automatically converts unit arg into a var."""
4448
4449    arg_types = {"unit": False}
4450
4451    UNABBREVIATED_UNIT_NAME = {
4452        "D": "DAY",
4453        "H": "HOUR",
4454        "M": "MINUTE",
4455        "MS": "MILLISECOND",
4456        "NS": "NANOSECOND",
4457        "Q": "QUARTER",
4458        "S": "SECOND",
4459        "US": "MICROSECOND",
4460        "W": "WEEK",
4461        "Y": "YEAR",
4462    }
4463
4464    VAR_LIKE = (Column, Literal, Var)
4465
4466    def __init__(self, **args):
4467        unit = args.get("unit")
4468        if isinstance(unit, self.VAR_LIKE):
4469            args["unit"] = Var(
4470                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4471            )
4472        elif isinstance(unit, Week):
4473            unit.set("this", Var(this=unit.this.name.upper()))
4474
4475        super().__init__(**args)
4476
4477    @property
4478    def unit(self) -> t.Optional[Var | IntervalSpan]:
4479        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4466    def __init__(self, **args):
4467        unit = args.get("unit")
4468        if isinstance(unit, self.VAR_LIKE):
4469            args["unit"] = Var(
4470                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4471            )
4472        elif isinstance(unit, Week):
4473            unit.set("this", Var(this=unit.this.name.upper()))
4474
4475        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]
4477    @property
4478    def unit(self) -> t.Optional[Var | IntervalSpan]:
4479        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4482class IntervalOp(TimeUnit):
4483    arg_types = {"unit": True, "expression": True}
4484
4485    def interval(self):
4486        return Interval(
4487            this=self.expression.copy(),
4488            unit=self.unit.copy(),
4489        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4485    def interval(self):
4486        return Interval(
4487            this=self.expression.copy(),
4488            unit=self.unit.copy(),
4489        )
key = 'intervalop'
class IntervalSpan(DataType):
4495class IntervalSpan(DataType):
4496    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4499class Interval(TimeUnit):
4500    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4503class IgnoreNulls(Expression):
4504    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4507class RespectNulls(Expression):
4508    pass
key = 'respectnulls'
class HavingMax(Expression):
4512class HavingMax(Expression):
4513    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4517class Func(Condition):
4518    """
4519    The base class for all function expressions.
4520
4521    Attributes:
4522        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4523            treated as a variable length argument and the argument's value will be stored as a list.
4524        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4525            function expression. These values are used to map this node to a name during parsing as
4526            well as to provide the function's name during SQL string generation. By default the SQL
4527            name is set to the expression's class name transformed to snake case.
4528    """
4529
4530    is_var_len_args = False
4531
4532    @classmethod
4533    def from_arg_list(cls, args):
4534        if cls.is_var_len_args:
4535            all_arg_keys = list(cls.arg_types)
4536            # If this function supports variable length argument treat the last argument as such.
4537            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4538            num_non_var = len(non_var_len_arg_keys)
4539
4540            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4541            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4542        else:
4543            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4544
4545        return cls(**args_dict)
4546
4547    @classmethod
4548    def sql_names(cls):
4549        if cls is Func:
4550            raise NotImplementedError(
4551                "SQL name is only supported by concrete function implementations"
4552            )
4553        if "_sql_names" not in cls.__dict__:
4554            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4555        return cls._sql_names
4556
4557    @classmethod
4558    def sql_name(cls):
4559        return cls.sql_names()[0]
4560
4561    @classmethod
4562    def default_parser_mappings(cls):
4563        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):
4532    @classmethod
4533    def from_arg_list(cls, args):
4534        if cls.is_var_len_args:
4535            all_arg_keys = list(cls.arg_types)
4536            # If this function supports variable length argument treat the last argument as such.
4537            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4538            num_non_var = len(non_var_len_arg_keys)
4539
4540            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4541            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4542        else:
4543            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4544
4545        return cls(**args_dict)
@classmethod
def sql_names(cls):
4547    @classmethod
4548    def sql_names(cls):
4549        if cls is Func:
4550            raise NotImplementedError(
4551                "SQL name is only supported by concrete function implementations"
4552            )
4553        if "_sql_names" not in cls.__dict__:
4554            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4555        return cls._sql_names
@classmethod
def sql_name(cls):
4557    @classmethod
4558    def sql_name(cls):
4559        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4561    @classmethod
4562    def default_parser_mappings(cls):
4563        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4566class AggFunc(Func):
4567    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4570class ParameterizedAgg(AggFunc):
4571    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4574class Abs(Func):
4575    pass
key = 'abs'
class ArgMax(AggFunc):
4578class ArgMax(AggFunc):
4579    arg_types = {"this": True, "expression": True, "count": False}
4580    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4583class ArgMin(AggFunc):
4584    arg_types = {"this": True, "expression": True, "count": False}
4585    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4588class ApproxTopK(AggFunc):
4589    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4592class Flatten(Func):
4593    pass
key = 'flatten'
class Transform(Func):
4597class Transform(Func):
4598    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4601class Anonymous(Func):
4602    arg_types = {"this": True, "expressions": False}
4603    is_var_len_args = True
4604
4605    @property
4606    def name(self) -> str:
4607        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
4605    @property
4606    def name(self) -> str:
4607        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4610class AnonymousAggFunc(AggFunc):
4611    arg_types = {"this": True, "expressions": False}
4612    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4616class CombinedAggFunc(AnonymousAggFunc):
4617    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4620class CombinedParameterizedAgg(ParameterizedAgg):
4621    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):
4626class Hll(AggFunc):
4627    arg_types = {"this": True, "expressions": False}
4628    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4631class ApproxDistinct(AggFunc):
4632    arg_types = {"this": True, "accuracy": False}
4633    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4636class Array(Func):
4637    arg_types = {"expressions": False}
4638    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4642class ToArray(Func):
4643    pass
key = 'toarray'
class ToChar(Func):
4648class ToChar(Func):
4649    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4654class ToNumber(Func):
4655    arg_types = {
4656        "this": True,
4657        "format": False,
4658        "nlsparam": False,
4659        "precision": False,
4660        "scale": False,
4661    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4665class Convert(Func):
4666    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4669class GenerateSeries(Func):
4670    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):
4673class ArrayAgg(AggFunc):
4674    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4677class ArrayUniqueAgg(AggFunc):
4678    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4681class ArrayAll(Func):
4682    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4686class ArrayAny(Func):
4687    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4690class ArrayConcat(Func):
4691    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4692    arg_types = {"this": True, "expressions": False}
4693    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4696class ArrayContains(Binary, Func):
4697    pass
key = 'arraycontains'
class ArrayContained(Binary):
4700class ArrayContained(Binary):
4701    pass
key = 'arraycontained'
class ArrayFilter(Func):
4704class ArrayFilter(Func):
4705    arg_types = {"this": True, "expression": True}
4706    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4709class ArrayToString(Func):
4710    arg_types = {"this": True, "expression": True, "null": False}
4711    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4714class ArrayOverlaps(Binary, Func):
4715    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4718class ArraySize(Func):
4719    arg_types = {"this": True, "expression": False}
4720    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4723class ArraySort(Func):
4724    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4727class ArraySum(Func):
4728    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4731class ArrayUnionAgg(AggFunc):
4732    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4735class Avg(AggFunc):
4736    pass
key = 'avg'
class AnyValue(AggFunc):
4739class AnyValue(AggFunc):
4740    pass
key = 'anyvalue'
class Lag(AggFunc):
4743class Lag(AggFunc):
4744    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4747class Lead(AggFunc):
4748    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4753class First(AggFunc):
4754    pass
key = 'first'
class Last(AggFunc):
4757class Last(AggFunc):
4758    pass
key = 'last'
class FirstValue(AggFunc):
4761class FirstValue(AggFunc):
4762    pass
key = 'firstvalue'
class LastValue(AggFunc):
4765class LastValue(AggFunc):
4766    pass
key = 'lastvalue'
class NthValue(AggFunc):
4769class NthValue(AggFunc):
4770    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4773class Case(Func):
4774    arg_types = {"this": False, "ifs": True, "default": False}
4775
4776    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4777        instance = maybe_copy(self, copy)
4778        instance.append(
4779            "ifs",
4780            If(
4781                this=maybe_parse(condition, copy=copy, **opts),
4782                true=maybe_parse(then, copy=copy, **opts),
4783            ),
4784        )
4785        return instance
4786
4787    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4788        instance = maybe_copy(self, copy)
4789        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4790        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:
4776    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4777        instance = maybe_copy(self, copy)
4778        instance.append(
4779            "ifs",
4780            If(
4781                this=maybe_parse(condition, copy=copy, **opts),
4782                true=maybe_parse(then, copy=copy, **opts),
4783            ),
4784        )
4785        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4787    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4788        instance = maybe_copy(self, copy)
4789        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4790        return instance
key = 'case'
class Cast(Func):
4793class Cast(Func):
4794    arg_types = {
4795        "this": True,
4796        "to": True,
4797        "format": False,
4798        "safe": False,
4799        "action": False,
4800    }
4801
4802    @property
4803    def name(self) -> str:
4804        return self.this.name
4805
4806    @property
4807    def to(self) -> DataType:
4808        return self.args["to"]
4809
4810    @property
4811    def output_name(self) -> str:
4812        return self.name
4813
4814    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4815        """
4816        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4817        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4818        array<int> != array<float>.
4819
4820        Args:
4821            dtypes: the data types to compare this Cast's DataType to.
4822
4823        Returns:
4824            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4825        """
4826        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4802    @property
4803    def name(self) -> str:
4804        return self.this.name
to: DataType
4806    @property
4807    def to(self) -> DataType:
4808        return self.args["to"]
output_name: str
4810    @property
4811    def output_name(self) -> str:
4812        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:
4814    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4815        """
4816        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4817        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4818        array<int> != array<float>.
4819
4820        Args:
4821            dtypes: the data types to compare this Cast's DataType to.
4822
4823        Returns:
4824            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4825        """
4826        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):
4829class TryCast(Cast):
4830    pass
key = 'trycast'
class CastToStrType(Func):
4833class CastToStrType(Func):
4834    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4837class Collate(Binary, Func):
4838    pass
key = 'collate'
class Ceil(Func):
4841class Ceil(Func):
4842    arg_types = {"this": True, "decimals": False}
4843    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4846class Coalesce(Func):
4847    arg_types = {"this": True, "expressions": False}
4848    is_var_len_args = True
4849    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4852class Chr(Func):
4853    arg_types = {"this": True, "charset": False, "expressions": False}
4854    is_var_len_args = True
4855    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4858class Concat(Func):
4859    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4860    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4863class ConcatWs(Concat):
4864    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4868class ConnectByRoot(Func):
4869    pass
key = 'connectbyroot'
class Count(AggFunc):
4872class Count(AggFunc):
4873    arg_types = {"this": False, "expressions": False}
4874    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4877class CountIf(AggFunc):
4878    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4882class Cbrt(Func):
4883    pass
key = 'cbrt'
class CurrentDate(Func):
4886class CurrentDate(Func):
4887    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4890class CurrentDatetime(Func):
4891    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4894class CurrentTime(Func):
4895    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4898class CurrentTimestamp(Func):
4899    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4902class CurrentUser(Func):
4903    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4906class DateAdd(Func, IntervalOp):
4907    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4910class DateSub(Func, IntervalOp):
4911    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4914class DateDiff(Func, TimeUnit):
4915    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4916    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4919class DateTrunc(Func):
4920    arg_types = {"unit": True, "this": True, "zone": False}
4921
4922    def __init__(self, **args):
4923        unit = args.get("unit")
4924        if isinstance(unit, TimeUnit.VAR_LIKE):
4925            args["unit"] = Literal.string(
4926                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4927            )
4928        elif isinstance(unit, Week):
4929            unit.set("this", Literal.string(unit.this.name.upper()))
4930
4931        super().__init__(**args)
4932
4933    @property
4934    def unit(self) -> Expression:
4935        return self.args["unit"]
DateTrunc(**args)
4922    def __init__(self, **args):
4923        unit = args.get("unit")
4924        if isinstance(unit, TimeUnit.VAR_LIKE):
4925            args["unit"] = Literal.string(
4926                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4927            )
4928        elif isinstance(unit, Week):
4929            unit.set("this", Literal.string(unit.this.name.upper()))
4930
4931        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4933    @property
4934    def unit(self) -> Expression:
4935        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4938class DatetimeAdd(Func, IntervalOp):
4939    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4942class DatetimeSub(Func, IntervalOp):
4943    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4946class DatetimeDiff(Func, TimeUnit):
4947    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4950class DatetimeTrunc(Func, TimeUnit):
4951    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4954class DayOfWeek(Func):
4955    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4958class DayOfMonth(Func):
4959    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4962class DayOfYear(Func):
4963    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4966class ToDays(Func):
4967    pass
key = 'todays'
class WeekOfYear(Func):
4970class WeekOfYear(Func):
4971    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4974class MonthsBetween(Func):
4975    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4978class LastDay(Func, TimeUnit):
4979    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4980    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4983class Extract(Func):
4984    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4987class Timestamp(Func):
4988    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4991class TimestampAdd(Func, TimeUnit):
4992    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4995class TimestampSub(Func, TimeUnit):
4996    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4999class TimestampDiff(Func, TimeUnit):
5000    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5001    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5004class TimestampTrunc(Func, TimeUnit):
5005    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5008class TimeAdd(Func, TimeUnit):
5009    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5012class TimeSub(Func, TimeUnit):
5013    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5016class TimeDiff(Func, TimeUnit):
5017    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5020class TimeTrunc(Func, TimeUnit):
5021    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5024class DateFromParts(Func):
5025    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5026    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5029class TimeFromParts(Func):
5030    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5031    arg_types = {
5032        "hour": True,
5033        "min": True,
5034        "sec": True,
5035        "nano": False,
5036        "fractions": False,
5037        "precision": False,
5038    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5041class DateStrToDate(Func):
5042    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5045class DateToDateStr(Func):
5046    pass
key = 'datetodatestr'
class DateToDi(Func):
5049class DateToDi(Func):
5050    pass
key = 'datetodi'
class Date(Func):
5054class Date(Func):
5055    arg_types = {"this": False, "zone": False, "expressions": False}
5056    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5059class Day(Func):
5060    pass
key = 'day'
class Decode(Func):
5063class Decode(Func):
5064    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5067class DiToDate(Func):
5068    pass
key = 'ditodate'
class Encode(Func):
5071class Encode(Func):
5072    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5075class Exp(Func):
5076    pass
key = 'exp'
class Explode(Func):
5080class Explode(Func):
5081    arg_types = {"this": True, "expressions": False}
5082    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5085class ExplodeOuter(Explode):
5086    pass
key = 'explodeouter'
class Posexplode(Explode):
5089class Posexplode(Explode):
5090    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5093class PosexplodeOuter(Posexplode, ExplodeOuter):
5094    pass
key = 'posexplodeouter'
class Floor(Func):
5097class Floor(Func):
5098    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5101class FromBase64(Func):
5102    pass
key = 'frombase64'
class ToBase64(Func):
5105class ToBase64(Func):
5106    pass
key = 'tobase64'
class GenerateDateArray(Func):
5109class GenerateDateArray(Func):
5110    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5113class Greatest(Func):
5114    arg_types = {"this": True, "expressions": False}
5115    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5118class GroupConcat(AggFunc):
5119    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5122class Hex(Func):
5123    pass
key = 'hex'
class Xor(Connector, Func):
5126class Xor(Connector, Func):
5127    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5130class If(Func):
5131    arg_types = {"this": True, "true": True, "false": False}
5132    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5135class Nullif(Func):
5136    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5139class Initcap(Func):
5140    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5143class IsNan(Func):
5144    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5147class IsInf(Func):
5148    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5151class JSONPath(Expression):
5152    arg_types = {"expressions": True}
5153
5154    @property
5155    def output_name(self) -> str:
5156        last_segment = self.expressions[-1].this
5157        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5154    @property
5155    def output_name(self) -> str:
5156        last_segment = self.expressions[-1].this
5157        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):
5160class JSONPathPart(Expression):
5161    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5164class JSONPathFilter(JSONPathPart):
5165    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5168class JSONPathKey(JSONPathPart):
5169    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5172class JSONPathRecursive(JSONPathPart):
5173    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5176class JSONPathRoot(JSONPathPart):
5177    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5180class JSONPathScript(JSONPathPart):
5181    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5184class JSONPathSlice(JSONPathPart):
5185    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5188class JSONPathSelector(JSONPathPart):
5189    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5192class JSONPathSubscript(JSONPathPart):
5193    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5196class JSONPathUnion(JSONPathPart):
5197    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5200class JSONPathWildcard(JSONPathPart):
5201    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5204class FormatJson(Expression):
5205    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5208class JSONKeyValue(Expression):
5209    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5212class JSONObject(Func):
5213    arg_types = {
5214        "expressions": False,
5215        "null_handling": False,
5216        "unique_keys": False,
5217        "return_type": False,
5218        "encoding": False,
5219    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5222class JSONObjectAgg(AggFunc):
5223    arg_types = {
5224        "expressions": False,
5225        "null_handling": False,
5226        "unique_keys": False,
5227        "return_type": False,
5228        "encoding": False,
5229    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5233class JSONArray(Func):
5234    arg_types = {
5235        "expressions": True,
5236        "null_handling": False,
5237        "return_type": False,
5238        "strict": False,
5239    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5243class JSONArrayAgg(Func):
5244    arg_types = {
5245        "this": True,
5246        "order": False,
5247        "null_handling": False,
5248        "return_type": False,
5249        "strict": False,
5250    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5255class JSONColumnDef(Expression):
5256    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):
5259class JSONSchema(Expression):
5260    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5264class JSONTable(Func):
5265    arg_types = {
5266        "this": True,
5267        "schema": True,
5268        "path": False,
5269        "error_handling": False,
5270        "empty_handling": False,
5271    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5274class OpenJSONColumnDef(Expression):
5275    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):
5278class OpenJSON(Func):
5279    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5282class JSONBContains(Binary):
5283    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5286class JSONExtract(Binary, Func):
5287    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5288    _sql_names = ["JSON_EXTRACT"]
5289    is_var_len_args = True
5290
5291    @property
5292    def output_name(self) -> str:
5293        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
5291    @property
5292    def output_name(self) -> str:
5293        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):
5296class JSONExtractScalar(Binary, Func):
5297    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5298    _sql_names = ["JSON_EXTRACT_SCALAR"]
5299    is_var_len_args = True
5300
5301    @property
5302    def output_name(self) -> str:
5303        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
5301    @property
5302    def output_name(self) -> str:
5303        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):
5306class JSONBExtract(Binary, Func):
5307    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5310class JSONBExtractScalar(Binary, Func):
5311    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5314class JSONFormat(Func):
5315    arg_types = {"this": False, "options": False}
5316    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5320class JSONArrayContains(Binary, Predicate, Func):
5321    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5324class ParseJSON(Func):
5325    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5326    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5327    arg_types = {"this": True, "expressions": False}
5328    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5331class Least(Func):
5332    arg_types = {"this": True, "expressions": False}
5333    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5336class Left(Func):
5337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5344class Length(Func):
5345    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5348class Levenshtein(Func):
5349    arg_types = {
5350        "this": True,
5351        "expression": False,
5352        "ins_cost": False,
5353        "del_cost": False,
5354        "sub_cost": False,
5355    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5358class Ln(Func):
5359    pass
key = 'ln'
class Log(Func):
5362class Log(Func):
5363    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5366class LogicalOr(AggFunc):
5367    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5370class LogicalAnd(AggFunc):
5371    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5374class Lower(Func):
5375    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5378class Map(Func):
5379    arg_types = {"keys": False, "values": False}
5380
5381    @property
5382    def keys(self) -> t.List[Expression]:
5383        keys = self.args.get("keys")
5384        return keys.expressions if keys else []
5385
5386    @property
5387    def values(self) -> t.List[Expression]:
5388        values = self.args.get("values")
5389        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5381    @property
5382    def keys(self) -> t.List[Expression]:
5383        keys = self.args.get("keys")
5384        return keys.expressions if keys else []
values: List[Expression]
5386    @property
5387    def values(self) -> t.List[Expression]:
5388        values = self.args.get("values")
5389        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5393class ToMap(Func):
5394    pass
key = 'tomap'
class MapFromEntries(Func):
5397class MapFromEntries(Func):
5398    pass
key = 'mapfromentries'
class StarMap(Func):
5401class StarMap(Func):
5402    pass
key = 'starmap'
class VarMap(Func):
5405class VarMap(Func):
5406    arg_types = {"keys": True, "values": True}
5407    is_var_len_args = True
5408
5409    @property
5410    def keys(self) -> t.List[Expression]:
5411        return self.args["keys"].expressions
5412
5413    @property
5414    def values(self) -> t.List[Expression]:
5415        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5409    @property
5410    def keys(self) -> t.List[Expression]:
5411        return self.args["keys"].expressions
values: List[Expression]
5413    @property
5414    def values(self) -> t.List[Expression]:
5415        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5419class MatchAgainst(Func):
5420    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5423class Max(AggFunc):
5424    arg_types = {"this": True, "expressions": False}
5425    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5428class MD5(Func):
5429    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5433class MD5Digest(Func):
5434    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5437class Min(AggFunc):
5438    arg_types = {"this": True, "expressions": False}
5439    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5442class Month(Func):
5443    pass
key = 'month'
class AddMonths(Func):
5446class AddMonths(Func):
5447    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5450class Nvl2(Func):
5451    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5455class Predict(Func):
5456    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5459class Pow(Binary, Func):
5460    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5463class PercentileCont(AggFunc):
5464    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5467class PercentileDisc(AggFunc):
5468    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5471class Quantile(AggFunc):
5472    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5475class ApproxQuantile(Quantile):
5476    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5479class Rand(Func):
5480    _sql_names = ["RAND", "RANDOM"]
5481    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5484class Randn(Func):
5485    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5488class RangeN(Func):
5489    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5492class ReadCSV(Func):
5493    _sql_names = ["READ_CSV"]
5494    is_var_len_args = True
5495    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5498class Reduce(Func):
5499    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):
5502class RegexpExtract(Func):
5503    arg_types = {
5504        "this": True,
5505        "expression": True,
5506        "position": False,
5507        "occurrence": False,
5508        "parameters": False,
5509        "group": False,
5510    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5513class RegexpReplace(Func):
5514    arg_types = {
5515        "this": True,
5516        "expression": True,
5517        "replacement": False,
5518        "position": False,
5519        "occurrence": False,
5520        "parameters": False,
5521        "modifiers": False,
5522    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5525class RegexpLike(Binary, Func):
5526    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5529class RegexpILike(Binary, Func):
5530    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5535class RegexpSplit(Func):
5536    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5539class Repeat(Func):
5540    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5545class Round(Func):
5546    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5549class RowNumber(Func):
5550    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5553class SafeDivide(Func):
5554    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5557class SHA(Func):
5558    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5561class SHA2(Func):
5562    _sql_names = ["SHA2"]
5563    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5566class Sign(Func):
5567    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5570class SortArray(Func):
5571    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5574class Split(Func):
5575    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5580class Substring(Func):
5581    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5584class StandardHash(Func):
5585    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5588class StartsWith(Func):
5589    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5590    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5593class StrPosition(Func):
5594    arg_types = {
5595        "this": True,
5596        "substr": True,
5597        "position": False,
5598        "instance": False,
5599    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5602class StrToDate(Func):
5603    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5606class StrToTime(Func):
5607    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5612class StrToUnix(Func):
5613    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5618class StrToMap(Func):
5619    arg_types = {
5620        "this": True,
5621        "pair_delim": False,
5622        "key_value_delim": False,
5623        "duplicate_resolution_callback": False,
5624    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5627class NumberToStr(Func):
5628    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5631class FromBase(Func):
5632    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5635class Struct(Func):
5636    arg_types = {"expressions": False}
5637    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5640class StructExtract(Func):
5641    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5646class Stuff(Func):
5647    _sql_names = ["STUFF", "INSERT"]
5648    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):
5651class Sum(AggFunc):
5652    pass
key = 'sum'
class Sqrt(Func):
5655class Sqrt(Func):
5656    pass
key = 'sqrt'
class Stddev(AggFunc):
5659class Stddev(AggFunc):
5660    pass
key = 'stddev'
class StddevPop(AggFunc):
5663class StddevPop(AggFunc):
5664    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5667class StddevSamp(AggFunc):
5668    pass
key = 'stddevsamp'
class TimeToStr(Func):
5671class TimeToStr(Func):
5672    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5675class TimeToTimeStr(Func):
5676    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5679class TimeToUnix(Func):
5680    pass
key = 'timetounix'
class TimeStrToDate(Func):
5683class TimeStrToDate(Func):
5684    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5687class TimeStrToTime(Func):
5688    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5691class TimeStrToUnix(Func):
5692    pass
key = 'timestrtounix'
class Trim(Func):
5695class Trim(Func):
5696    arg_types = {
5697        "this": True,
5698        "expression": False,
5699        "position": False,
5700        "collation": False,
5701    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5704class TsOrDsAdd(Func, TimeUnit):
5705    # return_type is used to correctly cast the arguments of this expression when transpiling it
5706    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5707
5708    @property
5709    def return_type(self) -> DataType:
5710        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
5708    @property
5709    def return_type(self) -> DataType:
5710        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5713class TsOrDsDiff(Func, TimeUnit):
5714    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5717class TsOrDsToDateStr(Func):
5718    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5721class TsOrDsToDate(Func):
5722    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5725class TsOrDsToTime(Func):
5726    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5729class TsOrDsToTimestamp(Func):
5730    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5733class TsOrDiToDi(Func):
5734    pass
key = 'tsorditodi'
class Unhex(Func):
5737class Unhex(Func):
5738    pass
key = 'unhex'
class UnixDate(Func):
5742class UnixDate(Func):
5743    pass
key = 'unixdate'
class UnixToStr(Func):
5746class UnixToStr(Func):
5747    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5752class UnixToTime(Func):
5753    arg_types = {
5754        "this": True,
5755        "scale": False,
5756        "zone": False,
5757        "hours": False,
5758        "minutes": False,
5759        "format": False,
5760    }
5761
5762    SECONDS = Literal.number(0)
5763    DECIS = Literal.number(1)
5764    CENTIS = Literal.number(2)
5765    MILLIS = Literal.number(3)
5766    DECIMILLIS = Literal.number(4)
5767    CENTIMILLIS = Literal.number(5)
5768    MICROS = Literal.number(6)
5769    DECIMICROS = Literal.number(7)
5770    CENTIMICROS = Literal.number(8)
5771    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):
5774class UnixToTimeStr(Func):
5775    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5778class TimestampFromParts(Func):
5779    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5780    arg_types = {
5781        "year": True,
5782        "month": True,
5783        "day": True,
5784        "hour": True,
5785        "min": True,
5786        "sec": True,
5787        "nano": False,
5788        "zone": False,
5789        "milli": False,
5790    }
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):
5793class Upper(Func):
5794    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5797class Corr(Binary, AggFunc):
5798    pass
key = 'corr'
class Variance(AggFunc):
5801class Variance(AggFunc):
5802    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5805class VariancePop(AggFunc):
5806    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5809class CovarSamp(Binary, AggFunc):
5810    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5813class CovarPop(Binary, AggFunc):
5814    pass
key = 'covarpop'
class Week(Func):
5817class Week(Func):
5818    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5821class XMLTable(Func):
5822    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):
5825class Year(Func):
5826    pass
key = 'year'
class Use(Expression):
5829class Use(Expression):
5830    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5833class Merge(Expression):
5834    arg_types = {
5835        "this": True,
5836        "using": True,
5837        "on": True,
5838        "expressions": True,
5839        "with": False,
5840    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5843class When(Func):
5844    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):
5849class NextValueFor(Func):
5850    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 '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'>, '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:
5888def maybe_parse(
5889    sql_or_expression: ExpOrStr,
5890    *,
5891    into: t.Optional[IntoType] = None,
5892    dialect: DialectType = None,
5893    prefix: t.Optional[str] = None,
5894    copy: bool = False,
5895    **opts,
5896) -> Expression:
5897    """Gracefully handle a possible string or expression.
5898
5899    Example:
5900        >>> maybe_parse("1")
5901        Literal(this=1, is_string=False)
5902        >>> maybe_parse(to_identifier("x"))
5903        Identifier(this=x, quoted=False)
5904
5905    Args:
5906        sql_or_expression: the SQL code string or an expression
5907        into: the SQLGlot Expression to parse into
5908        dialect: the dialect used to parse the input expressions (in the case that an
5909            input expression is a SQL string).
5910        prefix: a string to prefix the sql with before it gets parsed
5911            (automatically includes a space)
5912        copy: whether to copy the expression.
5913        **opts: other options to use to parse the input expressions (again, in the case
5914            that an input expression is a SQL string).
5915
5916    Returns:
5917        Expression: the parsed or given expression.
5918    """
5919    if isinstance(sql_or_expression, Expression):
5920        if copy:
5921            return sql_or_expression.copy()
5922        return sql_or_expression
5923
5924    if sql_or_expression is None:
5925        raise ParseError("SQL cannot be None")
5926
5927    import sqlglot
5928
5929    sql = str(sql_or_expression)
5930    if prefix:
5931        sql = f"{prefix} {sql}"
5932
5933    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):
5944def maybe_copy(instance, copy=True):
5945    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:
6159def union(
6160    left: ExpOrStr,
6161    right: ExpOrStr,
6162    distinct: bool = True,
6163    dialect: DialectType = None,
6164    copy: bool = True,
6165    **opts,
6166) -> Union:
6167    """
6168    Initializes a syntax tree from one UNION expression.
6169
6170    Example:
6171        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6172        'SELECT * FROM foo UNION SELECT * FROM bla'
6173
6174    Args:
6175        left: the SQL code string corresponding to the left-hand side.
6176            If an `Expression` instance is passed, it will be used as-is.
6177        right: the SQL code string corresponding to the right-hand side.
6178            If an `Expression` instance is passed, it will be used as-is.
6179        distinct: set the DISTINCT flag if and only if this is true.
6180        dialect: the dialect used to parse the input expression.
6181        copy: whether to copy the expression.
6182        opts: other options to use to parse the input expressions.
6183
6184    Returns:
6185        The new Union instance.
6186    """
6187    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6188    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6189
6190    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:
6193def intersect(
6194    left: ExpOrStr,
6195    right: ExpOrStr,
6196    distinct: bool = True,
6197    dialect: DialectType = None,
6198    copy: bool = True,
6199    **opts,
6200) -> Intersect:
6201    """
6202    Initializes a syntax tree from one INTERSECT expression.
6203
6204    Example:
6205        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6206        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6207
6208    Args:
6209        left: the SQL code string corresponding to the left-hand side.
6210            If an `Expression` instance is passed, it will be used as-is.
6211        right: the SQL code string corresponding to the right-hand side.
6212            If an `Expression` instance is passed, it will be used as-is.
6213        distinct: set the DISTINCT flag if and only if this is true.
6214        dialect: the dialect used to parse the input expression.
6215        copy: whether to copy the expression.
6216        opts: other options to use to parse the input expressions.
6217
6218    Returns:
6219        The new Intersect instance.
6220    """
6221    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6222    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6223
6224    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:
6227def except_(
6228    left: ExpOrStr,
6229    right: ExpOrStr,
6230    distinct: bool = True,
6231    dialect: DialectType = None,
6232    copy: bool = True,
6233    **opts,
6234) -> Except:
6235    """
6236    Initializes a syntax tree from one EXCEPT expression.
6237
6238    Example:
6239        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6240        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6241
6242    Args:
6243        left: the SQL code string corresponding to the left-hand side.
6244            If an `Expression` instance is passed, it will be used as-is.
6245        right: the SQL code string corresponding to the right-hand side.
6246            If an `Expression` instance is passed, it will be used as-is.
6247        distinct: set the DISTINCT flag if and only if this is true.
6248        dialect: the dialect used to parse the input expression.
6249        copy: whether to copy the expression.
6250        opts: other options to use to parse the input expressions.
6251
6252    Returns:
6253        The new Except instance.
6254    """
6255    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6256    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6257
6258    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:
6261def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6262    """
6263    Initializes a syntax tree from one or multiple SELECT expressions.
6264
6265    Example:
6266        >>> select("col1", "col2").from_("tbl").sql()
6267        'SELECT col1, col2 FROM tbl'
6268
6269    Args:
6270        *expressions: the SQL code string to parse as the expressions of a
6271            SELECT statement. If an Expression instance is passed, this is used as-is.
6272        dialect: the dialect used to parse the input expressions (in the case that an
6273            input expression is a SQL string).
6274        **opts: other options to use to parse the input expressions (again, in the case
6275            that an input expression is a SQL string).
6276
6277    Returns:
6278        Select: the syntax tree for the SELECT statement.
6279    """
6280    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:
6283def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6284    """
6285    Initializes a syntax tree from a FROM expression.
6286
6287    Example:
6288        >>> from_("tbl").select("col1", "col2").sql()
6289        'SELECT col1, col2 FROM tbl'
6290
6291    Args:
6292        *expression: the SQL code string to parse as the FROM expressions of a
6293            SELECT statement. If an Expression instance is passed, this is used as-is.
6294        dialect: the dialect used to parse the input expression (in the case that the
6295            input expression is a SQL string).
6296        **opts: other options to use to parse the input expressions (again, in the case
6297            that the input expression is a SQL string).
6298
6299    Returns:
6300        Select: the syntax tree for the SELECT statement.
6301    """
6302    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:
6305def update(
6306    table: str | Table,
6307    properties: dict,
6308    where: t.Optional[ExpOrStr] = None,
6309    from_: t.Optional[ExpOrStr] = None,
6310    dialect: DialectType = None,
6311    **opts,
6312) -> Update:
6313    """
6314    Creates an update statement.
6315
6316    Example:
6317        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6318        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6319
6320    Args:
6321        *properties: dictionary of properties to set which are
6322            auto converted to sql objects eg None -> NULL
6323        where: sql conditional parsed into a WHERE statement
6324        from_: sql statement parsed into a FROM statement
6325        dialect: the dialect used to parse the input expressions.
6326        **opts: other options to use to parse the input expressions.
6327
6328    Returns:
6329        Update: the syntax tree for the UPDATE statement.
6330    """
6331    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6332    update_expr.set(
6333        "expressions",
6334        [
6335            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6336            for k, v in properties.items()
6337        ],
6338    )
6339    if from_:
6340        update_expr.set(
6341            "from",
6342            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6343        )
6344    if isinstance(where, Condition):
6345        where = Where(this=where)
6346    if where:
6347        update_expr.set(
6348            "where",
6349            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6350        )
6351    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:
6354def delete(
6355    table: ExpOrStr,
6356    where: t.Optional[ExpOrStr] = None,
6357    returning: t.Optional[ExpOrStr] = None,
6358    dialect: DialectType = None,
6359    **opts,
6360) -> Delete:
6361    """
6362    Builds a delete statement.
6363
6364    Example:
6365        >>> delete("my_table", where="id > 1").sql()
6366        'DELETE FROM my_table WHERE id > 1'
6367
6368    Args:
6369        where: sql conditional parsed into a WHERE statement
6370        returning: sql conditional parsed into a RETURNING statement
6371        dialect: the dialect used to parse the input expressions.
6372        **opts: other options to use to parse the input expressions.
6373
6374    Returns:
6375        Delete: the syntax tree for the DELETE statement.
6376    """
6377    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6378    if where:
6379        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6380    if returning:
6381        delete_expr = t.cast(
6382            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6383        )
6384    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:
6387def insert(
6388    expression: ExpOrStr,
6389    into: ExpOrStr,
6390    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6391    overwrite: t.Optional[bool] = None,
6392    returning: t.Optional[ExpOrStr] = None,
6393    dialect: DialectType = None,
6394    copy: bool = True,
6395    **opts,
6396) -> Insert:
6397    """
6398    Builds an INSERT statement.
6399
6400    Example:
6401        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6402        'INSERT INTO tbl VALUES (1, 2, 3)'
6403
6404    Args:
6405        expression: the sql string or expression of the INSERT statement
6406        into: the tbl to insert data to.
6407        columns: optionally the table's column names.
6408        overwrite: whether to INSERT OVERWRITE or not.
6409        returning: sql conditional parsed into a RETURNING statement
6410        dialect: the dialect used to parse the input expressions.
6411        copy: whether to copy the expression.
6412        **opts: other options to use to parse the input expressions.
6413
6414    Returns:
6415        Insert: the syntax tree for the INSERT statement.
6416    """
6417    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6418    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6419
6420    if columns:
6421        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6422
6423    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6424
6425    if returning:
6426        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6427
6428    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:
6431def condition(
6432    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6433) -> Condition:
6434    """
6435    Initialize a logical condition expression.
6436
6437    Example:
6438        >>> condition("x=1").sql()
6439        'x = 1'
6440
6441        This is helpful for composing larger logical syntax trees:
6442        >>> where = condition("x=1")
6443        >>> where = where.and_("y=1")
6444        >>> Select().from_("tbl").select("*").where(where).sql()
6445        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6446
6447    Args:
6448        *expression: the SQL code string to parse.
6449            If an Expression instance is passed, this is used as-is.
6450        dialect: the dialect used to parse the input expression (in the case that the
6451            input expression is a SQL string).
6452        copy: Whether to copy `expression` (only applies to expressions).
6453        **opts: other options to use to parse the input expressions (again, in the case
6454            that the input expression is a SQL string).
6455
6456    Returns:
6457        The new Condition instance
6458    """
6459    return maybe_parse(
6460        expression,
6461        into=Condition,
6462        dialect=dialect,
6463        copy=copy,
6464        **opts,
6465    )

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:
6468def and_(
6469    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6470) -> Condition:
6471    """
6472    Combine multiple conditions with an AND logical operator.
6473
6474    Example:
6475        >>> and_("x=1", and_("y=1", "z=1")).sql()
6476        'x = 1 AND (y = 1 AND z = 1)'
6477
6478    Args:
6479        *expressions: the SQL code strings to parse.
6480            If an Expression instance is passed, this is used as-is.
6481        dialect: the dialect used to parse the input expression.
6482        copy: whether to copy `expressions` (only applies to Expressions).
6483        **opts: other options to use to parse the input expressions.
6484
6485    Returns:
6486        And: the new condition
6487    """
6488    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:
6491def or_(
6492    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6493) -> Condition:
6494    """
6495    Combine multiple conditions with an OR logical operator.
6496
6497    Example:
6498        >>> or_("x=1", or_("y=1", "z=1")).sql()
6499        'x = 1 OR (y = 1 OR z = 1)'
6500
6501    Args:
6502        *expressions: the SQL code strings to parse.
6503            If an Expression instance is passed, this is used as-is.
6504        dialect: the dialect used to parse the input expression.
6505        copy: whether to copy `expressions` (only applies to Expressions).
6506        **opts: other options to use to parse the input expressions.
6507
6508    Returns:
6509        Or: the new condition
6510    """
6511    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:
6514def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6515    """
6516    Wrap a condition with a NOT operator.
6517
6518    Example:
6519        >>> not_("this_suit='black'").sql()
6520        "NOT this_suit = 'black'"
6521
6522    Args:
6523        expression: the SQL code string to parse.
6524            If an Expression instance is passed, this is used as-is.
6525        dialect: the dialect used to parse the input expression.
6526        copy: whether to copy the expression or not.
6527        **opts: other options to use to parse the input expressions.
6528
6529    Returns:
6530        The new condition.
6531    """
6532    this = condition(
6533        expression,
6534        dialect=dialect,
6535        copy=copy,
6536        **opts,
6537    )
6538    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:
6541def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6542    """
6543    Wrap an expression in parentheses.
6544
6545    Example:
6546        >>> paren("5 + 3").sql()
6547        '(5 + 3)'
6548
6549    Args:
6550        expression: the SQL code string to parse.
6551            If an Expression instance is passed, this is used as-is.
6552        copy: whether to copy the expression or not.
6553
6554    Returns:
6555        The wrapped expression.
6556    """
6557    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):
6573def to_identifier(name, quoted=None, copy=True):
6574    """Builds an identifier.
6575
6576    Args:
6577        name: The name to turn into an identifier.
6578        quoted: Whether to force quote the identifier.
6579        copy: Whether to copy name if it's an Identifier.
6580
6581    Returns:
6582        The identifier ast node.
6583    """
6584
6585    if name is None:
6586        return None
6587
6588    if isinstance(name, Identifier):
6589        identifier = maybe_copy(name, copy)
6590    elif isinstance(name, str):
6591        identifier = Identifier(
6592            this=name,
6593            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6594        )
6595    else:
6596        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6597    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:
6600def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6601    """
6602    Parses a given string into an identifier.
6603
6604    Args:
6605        name: The name to parse into an identifier.
6606        dialect: The dialect to parse against.
6607
6608    Returns:
6609        The identifier ast node.
6610    """
6611    try:
6612        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6613    except ParseError:
6614        expression = to_identifier(name)
6615
6616    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:
6622def to_interval(interval: str | Literal) -> Interval:
6623    """Builds an interval expression from a string like '1 day' or '5 months'."""
6624    if isinstance(interval, Literal):
6625        if not interval.is_string:
6626            raise ValueError("Invalid interval string.")
6627
6628        interval = interval.this
6629
6630    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6631
6632    if not interval_parts:
6633        raise ValueError("Invalid interval string.")
6634
6635    return Interval(
6636        this=Literal.string(interval_parts.group(1)),
6637        unit=Var(this=interval_parts.group(2).upper()),
6638    )

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:
6641def to_table(
6642    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6643) -> Table:
6644    """
6645    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6646    If a table is passed in then that table is returned.
6647
6648    Args:
6649        sql_path: a `[catalog].[schema].[table]` string.
6650        dialect: the source dialect according to which the table name will be parsed.
6651        copy: Whether to copy a table if it is passed in.
6652        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6653
6654    Returns:
6655        A table expression.
6656    """
6657    if isinstance(sql_path, Table):
6658        return maybe_copy(sql_path, copy=copy)
6659
6660    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6661
6662    for k, v in kwargs.items():
6663        table.set(k, v)
6664
6665    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: bool = False, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6668def to_column(
6669    sql_path: str | Column,
6670    quoted: bool = False,
6671    dialect: DialectType = None,
6672    copy: bool = True,
6673    **kwargs,
6674) -> Column:
6675    """
6676    Create a column from a `[table].[column]` sql path. Table is optional.
6677    If a column is passed in then that column is returned.
6678
6679    Args:
6680        sql_path: a `[table].[column]` string.
6681        quoted: Whether or not to force quote identifiers.
6682        dialect: the source dialect according to which the column name will be parsed.
6683        copy: Whether to copy a column if it is passed in.
6684        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6685
6686    Returns:
6687        A column expression.
6688    """
6689    if isinstance(sql_path, Column):
6690        return maybe_copy(sql_path, copy=copy)
6691
6692    column = maybe_parse(sql_path, into=Column, dialect=dialect)
6693
6694    for k, v in kwargs.items():
6695        column.set(k, v)
6696
6697    if quoted:
6698        for i in column.find_all(Identifier):
6699            i.set("quoted", True)
6700
6701    return column

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):
6704def alias_(
6705    expression: ExpOrStr,
6706    alias: t.Optional[str | Identifier],
6707    table: bool | t.Sequence[str | Identifier] = False,
6708    quoted: t.Optional[bool] = None,
6709    dialect: DialectType = None,
6710    copy: bool = True,
6711    **opts,
6712):
6713    """Create an Alias expression.
6714
6715    Example:
6716        >>> alias_('foo', 'bar').sql()
6717        'foo AS bar'
6718
6719        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6720        '(SELECT 1, 2) AS bar(a, b)'
6721
6722    Args:
6723        expression: the SQL code strings to parse.
6724            If an Expression instance is passed, this is used as-is.
6725        alias: the alias name to use. If the name has
6726            special characters it is quoted.
6727        table: Whether to create a table alias, can also be a list of columns.
6728        quoted: whether to quote the alias
6729        dialect: the dialect used to parse the input expression.
6730        copy: Whether to copy the expression.
6731        **opts: other options to use to parse the input expressions.
6732
6733    Returns:
6734        Alias: the aliased expression
6735    """
6736    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6737    alias = to_identifier(alias, quoted=quoted)
6738
6739    if table:
6740        table_alias = TableAlias(this=alias)
6741        exp.set("alias", table_alias)
6742
6743        if not isinstance(table, bool):
6744            for column in table:
6745                table_alias.append("columns", to_identifier(column, quoted=quoted))
6746
6747        return exp
6748
6749    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6750    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6751    # for the complete Window expression.
6752    #
6753    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6754
6755    if "alias" in exp.arg_types and not isinstance(exp, Window):
6756        exp.set("alias", alias)
6757        return exp
6758    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:
6761def subquery(
6762    expression: ExpOrStr,
6763    alias: t.Optional[Identifier | str] = None,
6764    dialect: DialectType = None,
6765    **opts,
6766) -> Select:
6767    """
6768    Build a subquery expression that's selected from.
6769
6770    Example:
6771        >>> subquery('select x from tbl', 'bar').select('x').sql()
6772        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6773
6774    Args:
6775        expression: the SQL code strings to parse.
6776            If an Expression instance is passed, this is used as-is.
6777        alias: the alias name to use.
6778        dialect: the dialect used to parse the input expression.
6779        **opts: other options to use to parse the input expressions.
6780
6781    Returns:
6782        A new Select instance with the subquery expression included.
6783    """
6784
6785    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6786    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):
6817def column(
6818    col,
6819    table=None,
6820    db=None,
6821    catalog=None,
6822    *,
6823    fields=None,
6824    quoted=None,
6825    copy=True,
6826):
6827    """
6828    Build a Column.
6829
6830    Args:
6831        col: Column name.
6832        table: Table name.
6833        db: Database name.
6834        catalog: Catalog name.
6835        fields: Additional fields using dots.
6836        quoted: Whether to force quotes on the column's identifiers.
6837        copy: Whether to copy identifiers if passed in.
6838
6839    Returns:
6840        The new Column instance.
6841    """
6842    this = Column(
6843        this=to_identifier(col, quoted=quoted, copy=copy),
6844        table=to_identifier(table, quoted=quoted, copy=copy),
6845        db=to_identifier(db, quoted=quoted, copy=copy),
6846        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6847    )
6848
6849    if fields:
6850        this = Dot.build(
6851            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
6852        )
6853    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:
6856def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6857    """Cast an expression to a data type.
6858
6859    Example:
6860        >>> cast('x + 1', 'int').sql()
6861        'CAST(x + 1 AS INT)'
6862
6863    Args:
6864        expression: The expression to cast.
6865        to: The datatype to cast to.
6866        copy: Whether to copy the supplied expressions.
6867
6868    Returns:
6869        The new Cast instance.
6870    """
6871    expression = maybe_parse(expression, copy=copy, **opts)
6872    data_type = DataType.build(to, copy=copy, **opts)
6873    expression = Cast(this=expression, to=data_type)
6874    expression.type = data_type
6875    return expression

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
6878def table_(
6879    table: Identifier | str,
6880    db: t.Optional[Identifier | str] = None,
6881    catalog: t.Optional[Identifier | str] = None,
6882    quoted: t.Optional[bool] = None,
6883    alias: t.Optional[Identifier | str] = None,
6884) -> Table:
6885    """Build a Table.
6886
6887    Args:
6888        table: Table name.
6889        db: Database name.
6890        catalog: Catalog name.
6891        quote: Whether to force quotes on the table's identifiers.
6892        alias: Table's alias.
6893
6894    Returns:
6895        The new Table instance.
6896    """
6897    return Table(
6898        this=to_identifier(table, quoted=quoted) if table else None,
6899        db=to_identifier(db, quoted=quoted) if db else None,
6900        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6901        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6902    )

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:
6905def values(
6906    values: t.Iterable[t.Tuple[t.Any, ...]],
6907    alias: t.Optional[str] = None,
6908    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6909) -> Values:
6910    """Build VALUES statement.
6911
6912    Example:
6913        >>> values([(1, '2')]).sql()
6914        "VALUES (1, '2')"
6915
6916    Args:
6917        values: values statements that will be converted to SQL
6918        alias: optional alias
6919        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6920         If either are provided then an alias is also required.
6921
6922    Returns:
6923        Values: the Values expression object
6924    """
6925    if columns and not alias:
6926        raise ValueError("Alias is required when providing columns")
6927
6928    return Values(
6929        expressions=[convert(tup) for tup in values],
6930        alias=(
6931            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6932            if columns
6933            else (TableAlias(this=to_identifier(alias)) if alias else None)
6934        ),
6935    )

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:
6938def var(name: t.Optional[ExpOrStr]) -> Var:
6939    """Build a SQL variable.
6940
6941    Example:
6942        >>> repr(var('x'))
6943        'Var(this=x)'
6944
6945        >>> repr(var(column('x', table='y')))
6946        'Var(this=x)'
6947
6948    Args:
6949        name: The name of the var or an expression who's name will become the var.
6950
6951    Returns:
6952        The new variable node.
6953    """
6954    if not name:
6955        raise ValueError("Cannot convert empty name into var.")
6956
6957    if isinstance(name, Expression):
6958        name = name.name
6959    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:
6962def rename_table(
6963    old_name: str | Table,
6964    new_name: str | Table,
6965    dialect: DialectType = None,
6966) -> AlterTable:
6967    """Build ALTER TABLE... RENAME... expression
6968
6969    Args:
6970        old_name: The old name of the table
6971        new_name: The new name of the table
6972        dialect: The dialect to parse the table.
6973
6974    Returns:
6975        Alter table expression
6976    """
6977    old_table = to_table(old_name, dialect=dialect)
6978    new_table = to_table(new_name, dialect=dialect)
6979    return AlterTable(
6980        this=old_table,
6981        actions=[
6982            RenameTable(this=new_table),
6983        ],
6984    )

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:
6987def rename_column(
6988    table_name: str | Table,
6989    old_column_name: str | Column,
6990    new_column_name: str | Column,
6991    exists: t.Optional[bool] = None,
6992    dialect: DialectType = None,
6993) -> AlterTable:
6994    """Build ALTER TABLE... RENAME COLUMN... expression
6995
6996    Args:
6997        table_name: Name of the table
6998        old_column: The old name of the column
6999        new_column: The new name of the column
7000        exists: Whether to add the `IF EXISTS` clause
7001        dialect: The dialect to parse the table/column.
7002
7003    Returns:
7004        Alter table expression
7005    """
7006    table = to_table(table_name, dialect=dialect)
7007    old_column = to_column(old_column_name, dialect=dialect)
7008    new_column = to_column(new_column_name, dialect=dialect)
7009    return AlterTable(
7010        this=table,
7011        actions=[
7012            RenameColumn(this=old_column, to=new_column, exists=exists),
7013        ],
7014    )

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:
7017def convert(value: t.Any, copy: bool = False) -> Expression:
7018    """Convert a python value into an expression object.
7019
7020    Raises an error if a conversion is not possible.
7021
7022    Args:
7023        value: A python object.
7024        copy: Whether to copy `value` (only applies to Expressions and collections).
7025
7026    Returns:
7027        The equivalent expression object.
7028    """
7029    if isinstance(value, Expression):
7030        return maybe_copy(value, copy)
7031    if isinstance(value, str):
7032        return Literal.string(value)
7033    if isinstance(value, bool):
7034        return Boolean(this=value)
7035    if value is None or (isinstance(value, float) and math.isnan(value)):
7036        return null()
7037    if isinstance(value, numbers.Number):
7038        return Literal.number(value)
7039    if isinstance(value, bytes):
7040        return HexString(this=value.hex())
7041    if isinstance(value, datetime.datetime):
7042        datetime_literal = Literal.string(
7043            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7044                sep=" "
7045            )
7046        )
7047        return TimeStrToTime(this=datetime_literal)
7048    if isinstance(value, datetime.date):
7049        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7050        return DateStrToDate(this=date_literal)
7051    if isinstance(value, tuple):
7052        if hasattr(value, "_fields"):
7053            return Struct(
7054                expressions=[
7055                    PropertyEQ(
7056                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7057                    )
7058                    for k in value._fields
7059                ]
7060            )
7061        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7062    if isinstance(value, list):
7063        return Array(expressions=[convert(v, copy=copy) for v in value])
7064    if isinstance(value, dict):
7065        return Map(
7066            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7067            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7068        )
7069    if hasattr(value, "__dict__"):
7070        return Struct(
7071            expressions=[
7072                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7073                for k, v in value.__dict__.items()
7074            ]
7075        )
7076    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:
7079def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7080    """
7081    Replace children of an expression with the result of a lambda fun(child) -> exp.
7082    """
7083    for k, v in tuple(expression.args.items()):
7084        is_list_arg = type(v) is list
7085
7086        child_nodes = v if is_list_arg else [v]
7087        new_child_nodes = []
7088
7089        for cn in child_nodes:
7090            if isinstance(cn, Expression):
7091                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7092                    new_child_nodes.append(child_node)
7093            else:
7094                new_child_nodes.append(cn)
7095
7096        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:
7099def replace_tree(
7100    expression: Expression,
7101    fun: t.Callable,
7102    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7103) -> Expression:
7104    """
7105    Replace an entire tree with the result of function calls on each node.
7106
7107    This will be traversed in reverse dfs, so leaves first.
7108    If new nodes are created as a result of function calls, they will also be traversed.
7109    """
7110    stack = list(expression.dfs(prune=prune))
7111
7112    while stack:
7113        node = stack.pop()
7114        new_node = fun(node)
7115
7116        if new_node is not node:
7117            node.replace(new_node)
7118
7119            if isinstance(new_node, Expression):
7120                stack.append(new_node)
7121
7122    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]:
7125def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7126    """
7127    Return all table names referenced through columns in an expression.
7128
7129    Example:
7130        >>> import sqlglot
7131        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7132        ['a', 'c']
7133
7134    Args:
7135        expression: expression to find table names.
7136        exclude: a table name to exclude
7137
7138    Returns:
7139        A list of unique names.
7140    """
7141    return {
7142        table
7143        for table in (column.table for column in expression.find_all(Column))
7144        if table and table != exclude
7145    }

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:
7148def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7149    """Get the full name of a table as a string.
7150
7151    Args:
7152        table: Table expression node or string.
7153        dialect: The dialect to generate the table name for.
7154        identify: Determines when an identifier should be quoted. Possible values are:
7155            False (default): Never quote, except in cases where it's mandatory by the dialect.
7156            True: Always quote.
7157
7158    Examples:
7159        >>> from sqlglot import exp, parse_one
7160        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7161        'a.b.c'
7162
7163    Returns:
7164        The table name.
7165    """
7166
7167    table = maybe_parse(table, into=Table, dialect=dialect)
7168
7169    if not table:
7170        raise ValueError(f"Cannot parse {table}")
7171
7172    return ".".join(
7173        (
7174            part.sql(dialect=dialect, identify=True, copy=False)
7175            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7176            else part.name
7177        )
7178        for part in table.parts
7179    )

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:
7182def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7183    """Returns a case normalized table name without quotes.
7184
7185    Args:
7186        table: the table to normalize
7187        dialect: the dialect to use for normalization rules
7188        copy: whether to copy the expression.
7189
7190    Examples:
7191        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7192        'A-B.c'
7193    """
7194    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7195
7196    return ".".join(
7197        p.name
7198        for p in normalize_identifiers(
7199            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7200        ).parts
7201    )

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:
7204def replace_tables(
7205    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7206) -> E:
7207    """Replace all tables in expression according to the mapping.
7208
7209    Args:
7210        expression: expression node to be transformed and replaced.
7211        mapping: mapping of table names.
7212        dialect: the dialect of the mapping table
7213        copy: whether to copy the expression.
7214
7215    Examples:
7216        >>> from sqlglot import exp, parse_one
7217        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7218        'SELECT * FROM c /* a.b */'
7219
7220    Returns:
7221        The mapped expression.
7222    """
7223
7224    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7225
7226    def _replace_tables(node: Expression) -> Expression:
7227        if isinstance(node, Table):
7228            original = normalize_table_name(node, dialect=dialect)
7229            new_name = mapping.get(original)
7230
7231            if new_name:
7232                table = to_table(
7233                    new_name,
7234                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7235                    dialect=dialect,
7236                )
7237                table.add_comments([original])
7238                return table
7239        return node
7240
7241    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:
7244def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7245    """Replace placeholders in an expression.
7246
7247    Args:
7248        expression: expression node to be transformed and replaced.
7249        args: positional names that will substitute unnamed placeholders in the given order.
7250        kwargs: keyword arguments that will substitute named placeholders.
7251
7252    Examples:
7253        >>> from sqlglot import exp, parse_one
7254        >>> replace_placeholders(
7255        ...     parse_one("select * from :tbl where ? = ?"),
7256        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7257        ... ).sql()
7258        "SELECT * FROM foo WHERE str_col = 'b'"
7259
7260    Returns:
7261        The mapped expression.
7262    """
7263
7264    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7265        if isinstance(node, Placeholder):
7266            if node.this:
7267                new_name = kwargs.get(node.this)
7268                if new_name is not None:
7269                    return convert(new_name)
7270            else:
7271                try:
7272                    return convert(next(args))
7273                except StopIteration:
7274                    pass
7275        return node
7276
7277    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:
7280def expand(
7281    expression: Expression,
7282    sources: t.Dict[str, Query],
7283    dialect: DialectType = None,
7284    copy: bool = True,
7285) -> Expression:
7286    """Transforms an expression by expanding all referenced sources into subqueries.
7287
7288    Examples:
7289        >>> from sqlglot import parse_one
7290        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7291        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7292
7293        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7294        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7295
7296    Args:
7297        expression: The expression to expand.
7298        sources: A dictionary of name to Queries.
7299        dialect: The dialect of the sources dict.
7300        copy: Whether to copy the expression during transformation. Defaults to True.
7301
7302    Returns:
7303        The transformed expression.
7304    """
7305    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7306
7307    def _expand(node: Expression):
7308        if isinstance(node, Table):
7309            name = normalize_table_name(node, dialect=dialect)
7310            source = sources.get(name)
7311            if source:
7312                subquery = source.subquery(node.alias or name)
7313                subquery.comments = [f"source: {name}"]
7314                return subquery.transform(_expand, copy=False)
7315        return node
7316
7317    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:
7320def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7321    """
7322    Returns a Func expression.
7323
7324    Examples:
7325        >>> func("abs", 5).sql()
7326        'ABS(5)'
7327
7328        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7329        'CAST(5 AS DOUBLE)'
7330
7331    Args:
7332        name: the name of the function to build.
7333        args: the args used to instantiate the function of interest.
7334        copy: whether to copy the argument expressions.
7335        dialect: the source dialect.
7336        kwargs: the kwargs used to instantiate the function of interest.
7337
7338    Note:
7339        The arguments `args` and `kwargs` are mutually exclusive.
7340
7341    Returns:
7342        An instance of the function of interest, or an anonymous function, if `name` doesn't
7343        correspond to an existing `sqlglot.expressions.Func` class.
7344    """
7345    if args and kwargs:
7346        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7347
7348    from sqlglot.dialects.dialect import Dialect
7349
7350    dialect = Dialect.get_or_raise(dialect)
7351
7352    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7353    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7354
7355    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7356    if constructor:
7357        if converted:
7358            if "dialect" in constructor.__code__.co_varnames:
7359                function = constructor(converted, dialect=dialect)
7360            else:
7361                function = constructor(converted)
7362        elif constructor.__name__ == "from_arg_list":
7363            function = constructor.__self__(**kwargs)  # type: ignore
7364        else:
7365            constructor = FUNCTION_BY_NAME.get(name.upper())
7366            if constructor:
7367                function = constructor(**kwargs)
7368            else:
7369                raise ValueError(
7370                    f"Unable to convert '{name}' into a Func. Either manually construct "
7371                    "the Func expression of interest or parse the function call."
7372                )
7373    else:
7374        kwargs = kwargs or {"expressions": converted}
7375        function = Anonymous(this=name, **kwargs)
7376
7377    for error_message in function.error_messages(converted):
7378        raise ValueError(error_message)
7379
7380    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:
7383def case(
7384    expression: t.Optional[ExpOrStr] = None,
7385    **opts,
7386) -> Case:
7387    """
7388    Initialize a CASE statement.
7389
7390    Example:
7391        case().when("a = 1", "foo").else_("bar")
7392
7393    Args:
7394        expression: Optionally, the input expression (not all dialects support this)
7395        **opts: Extra keyword arguments for parsing `expression`
7396    """
7397    if expression is not None:
7398        this = maybe_parse(expression, **opts)
7399    else:
7400        this = None
7401    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
7404def cast_unless(
7405    expression: ExpOrStr,
7406    to: DATA_TYPE,
7407    *types: DATA_TYPE,
7408    **opts: t.Any,
7409) -> Expression | Cast:
7410    """
7411    Cast an expression to a data type unless it is a specified type.
7412
7413    Args:
7414        expression: The expression to cast.
7415        to: The data type to cast to.
7416        **types: The types to exclude from casting.
7417        **opts: Extra keyword arguments for parsing `expression`
7418    """
7419    expr = maybe_parse(expression, **opts)
7420    if expr.is_type(*types):
7421        return expr
7422    return cast(expr, to, **opts)

Cast an expression to a data type unless it is a specified type.

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7425def array(
7426    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7427) -> Array:
7428    """
7429    Returns an array.
7430
7431    Examples:
7432        >>> array(1, 'x').sql()
7433        'ARRAY(1, x)'
7434
7435    Args:
7436        expressions: the expressions to add to the array.
7437        copy: whether to copy the argument expressions.
7438        dialect: the source dialect.
7439        kwargs: the kwargs used to instantiate the function of interest.
7440
7441    Returns:
7442        An array expression.
7443    """
7444    return Array(
7445        expressions=[
7446            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7447            for expression in expressions
7448        ]
7449    )

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

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

Returns a true Boolean expression.

def false() -> Boolean:
7486def false() -> Boolean:
7487    """
7488    Returns a false Boolean expression.
7489    """
7490    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7493def null() -> Null:
7494    """
7495    Returns a Null expression.
7496    """
7497    return Null()

Returns a Null expression.

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