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

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

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):
1832class Drop(Expression):
1833    arg_types = {
1834        "this": False,
1835        "kind": False,
1836        "expressions": False,
1837        "exists": False,
1838        "temporary": False,
1839        "materialized": False,
1840        "cascade": False,
1841        "constraints": False,
1842        "purge": False,
1843    }
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):
1846class Filter(Expression):
1847    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1850class Check(Expression):
1851    pass
key = 'check'
class Connect(Expression):
1855class Connect(Expression):
1856    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class Prior(Expression):
1859class Prior(Expression):
1860    pass
key = 'prior'
class Directory(Expression):
1863class Directory(Expression):
1864    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1865    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1868class ForeignKey(Expression):
1869    arg_types = {
1870        "expressions": True,
1871        "reference": False,
1872        "delete": False,
1873        "update": False,
1874    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1877class ColumnPrefix(Expression):
1878    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1881class PrimaryKey(Expression):
1882    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1887class Into(Expression):
1888    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1891class From(Expression):
1892    @property
1893    def name(self) -> str:
1894        return self.this.name
1895
1896    @property
1897    def alias_or_name(self) -> str:
1898        return self.this.alias_or_name
name: str
1892    @property
1893    def name(self) -> str:
1894        return self.this.name
alias_or_name: str
1896    @property
1897    def alias_or_name(self) -> str:
1898        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1901class Having(Expression):
1902    pass
key = 'having'
class Hint(Expression):
1905class Hint(Expression):
1906    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1909class JoinHint(Expression):
1910    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1913class Identifier(Expression):
1914    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1915
1916    @property
1917    def quoted(self) -> bool:
1918        return bool(self.args.get("quoted"))
1919
1920    @property
1921    def hashable_args(self) -> t.Any:
1922        return (self.this, self.quoted)
1923
1924    @property
1925    def output_name(self) -> str:
1926        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1916    @property
1917    def quoted(self) -> bool:
1918        return bool(self.args.get("quoted"))
hashable_args: Any
1920    @property
1921    def hashable_args(self) -> t.Any:
1922        return (self.this, self.quoted)
output_name: str
1924    @property
1925    def output_name(self) -> str:
1926        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):
1930class Opclass(Expression):
1931    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1934class Index(Expression):
1935    arg_types = {
1936        "this": False,
1937        "table": False,
1938        "unique": False,
1939        "primary": False,
1940        "amp": False,  # teradata
1941        "params": False,
1942    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1945class IndexParameters(Expression):
1946    arg_types = {
1947        "using": False,
1948        "include": False,
1949        "columns": False,
1950        "with_storage": False,
1951        "partition_by": False,
1952        "tablespace": False,
1953        "where": False,
1954    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1957class Insert(DDL, DML):
1958    arg_types = {
1959        "hint": False,
1960        "with": False,
1961        "is_function": False,
1962        "this": True,
1963        "expression": False,
1964        "conflict": False,
1965        "returning": False,
1966        "overwrite": False,
1967        "exists": False,
1968        "partition": False,
1969        "alternative": False,
1970        "where": False,
1971        "ignore": False,
1972        "by_name": False,
1973    }
1974
1975    def with_(
1976        self,
1977        alias: ExpOrStr,
1978        as_: ExpOrStr,
1979        recursive: t.Optional[bool] = None,
1980        append: bool = True,
1981        dialect: DialectType = None,
1982        copy: bool = True,
1983        **opts,
1984    ) -> Insert:
1985        """
1986        Append to or set the common table expressions.
1987
1988        Example:
1989            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1990            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1991
1992        Args:
1993            alias: the SQL code string to parse as the table name.
1994                If an `Expression` instance is passed, this is used as-is.
1995            as_: the SQL code string to parse as the table expression.
1996                If an `Expression` instance is passed, it will be used as-is.
1997            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1998            append: if `True`, add to any existing expressions.
1999                Otherwise, this resets the expressions.
2000            dialect: the dialect used to parse the input expression.
2001            copy: if `False`, modify this expression instance in-place.
2002            opts: other options to use to parse the input expressions.
2003
2004        Returns:
2005            The modified expression.
2006        """
2007        return _apply_cte_builder(
2008            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2009        )
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:
1975    def with_(
1976        self,
1977        alias: ExpOrStr,
1978        as_: ExpOrStr,
1979        recursive: t.Optional[bool] = None,
1980        append: bool = True,
1981        dialect: DialectType = None,
1982        copy: bool = True,
1983        **opts,
1984    ) -> Insert:
1985        """
1986        Append to or set the common table expressions.
1987
1988        Example:
1989            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1990            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1991
1992        Args:
1993            alias: the SQL code string to parse as the table name.
1994                If an `Expression` instance is passed, this is used as-is.
1995            as_: the SQL code string to parse as the table expression.
1996                If an `Expression` instance is passed, it will be used as-is.
1997            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1998            append: if `True`, add to any existing expressions.
1999                Otherwise, this resets the expressions.
2000            dialect: the dialect used to parse the input expression.
2001            copy: if `False`, modify this expression instance in-place.
2002            opts: other options to use to parse the input expressions.
2003
2004        Returns:
2005            The modified expression.
2006        """
2007        return _apply_cte_builder(
2008            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2009        )

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):
2012class OnConflict(Expression):
2013    arg_types = {
2014        "duplicate": False,
2015        "expressions": False,
2016        "action": False,
2017        "conflict_keys": False,
2018        "constraint": False,
2019    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2022class Returning(Expression):
2023    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2027class Introducer(Expression):
2028    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2032class National(Expression):
2033    pass
key = 'national'
class LoadData(Expression):
2036class LoadData(Expression):
2037    arg_types = {
2038        "this": True,
2039        "local": False,
2040        "overwrite": False,
2041        "inpath": True,
2042        "partition": False,
2043        "input_format": False,
2044        "serde": False,
2045    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2048class Partition(Expression):
2049    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2052class PartitionRange(Expression):
2053    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2056class Fetch(Expression):
2057    arg_types = {
2058        "direction": False,
2059        "count": False,
2060        "percent": False,
2061        "with_ties": False,
2062    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2065class Group(Expression):
2066    arg_types = {
2067        "expressions": False,
2068        "grouping_sets": False,
2069        "cube": False,
2070        "rollup": False,
2071        "totals": False,
2072        "all": False,
2073    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2076class Lambda(Expression):
2077    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2080class Limit(Expression):
2081    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):
2084class Literal(Condition):
2085    arg_types = {"this": True, "is_string": True}
2086
2087    @property
2088    def hashable_args(self) -> t.Any:
2089        return (self.this, self.args.get("is_string"))
2090
2091    @classmethod
2092    def number(cls, number) -> Literal:
2093        return cls(this=str(number), is_string=False)
2094
2095    @classmethod
2096    def string(cls, string) -> Literal:
2097        return cls(this=str(string), is_string=True)
2098
2099    @property
2100    def output_name(self) -> str:
2101        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2087    @property
2088    def hashable_args(self) -> t.Any:
2089        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2091    @classmethod
2092    def number(cls, number) -> Literal:
2093        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2095    @classmethod
2096    def string(cls, string) -> Literal:
2097        return cls(this=str(string), is_string=True)
output_name: str
2099    @property
2100    def output_name(self) -> str:
2101        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):
2104class Join(Expression):
2105    arg_types = {
2106        "this": True,
2107        "on": False,
2108        "side": False,
2109        "kind": False,
2110        "using": False,
2111        "method": False,
2112        "global": False,
2113        "hint": False,
2114        "match_condition": False,  # Snowflake
2115    }
2116
2117    @property
2118    def method(self) -> str:
2119        return self.text("method").upper()
2120
2121    @property
2122    def kind(self) -> str:
2123        return self.text("kind").upper()
2124
2125    @property
2126    def side(self) -> str:
2127        return self.text("side").upper()
2128
2129    @property
2130    def hint(self) -> str:
2131        return self.text("hint").upper()
2132
2133    @property
2134    def alias_or_name(self) -> str:
2135        return self.this.alias_or_name
2136
2137    def on(
2138        self,
2139        *expressions: t.Optional[ExpOrStr],
2140        append: bool = True,
2141        dialect: DialectType = None,
2142        copy: bool = True,
2143        **opts,
2144    ) -> Join:
2145        """
2146        Append to or set the ON expressions.
2147
2148        Example:
2149            >>> import sqlglot
2150            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2151            'JOIN x ON y = 1'
2152
2153        Args:
2154            *expressions: the SQL code strings to parse.
2155                If an `Expression` instance is passed, it will be used as-is.
2156                Multiple expressions are combined with an AND operator.
2157            append: if `True`, AND the new expressions to any existing expression.
2158                Otherwise, this resets the expression.
2159            dialect: the dialect used to parse the input expressions.
2160            copy: if `False`, modify this expression instance in-place.
2161            opts: other options to use to parse the input expressions.
2162
2163        Returns:
2164            The modified Join expression.
2165        """
2166        join = _apply_conjunction_builder(
2167            *expressions,
2168            instance=self,
2169            arg="on",
2170            append=append,
2171            dialect=dialect,
2172            copy=copy,
2173            **opts,
2174        )
2175
2176        if join.kind == "CROSS":
2177            join.set("kind", None)
2178
2179        return join
2180
2181    def using(
2182        self,
2183        *expressions: t.Optional[ExpOrStr],
2184        append: bool = True,
2185        dialect: DialectType = None,
2186        copy: bool = True,
2187        **opts,
2188    ) -> Join:
2189        """
2190        Append to or set the USING expressions.
2191
2192        Example:
2193            >>> import sqlglot
2194            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2195            'JOIN x USING (foo, bla)'
2196
2197        Args:
2198            *expressions: the SQL code strings to parse.
2199                If an `Expression` instance is passed, it will be used as-is.
2200            append: if `True`, concatenate the new expressions to the existing "using" list.
2201                Otherwise, this resets the expression.
2202            dialect: the dialect used to parse the input expressions.
2203            copy: if `False`, modify this expression instance in-place.
2204            opts: other options to use to parse the input expressions.
2205
2206        Returns:
2207            The modified Join expression.
2208        """
2209        join = _apply_list_builder(
2210            *expressions,
2211            instance=self,
2212            arg="using",
2213            append=append,
2214            dialect=dialect,
2215            copy=copy,
2216            **opts,
2217        )
2218
2219        if join.kind == "CROSS":
2220            join.set("kind", None)
2221
2222        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
2117    @property
2118    def method(self) -> str:
2119        return self.text("method").upper()
kind: str
2121    @property
2122    def kind(self) -> str:
2123        return self.text("kind").upper()
side: str
2125    @property
2126    def side(self) -> str:
2127        return self.text("side").upper()
hint: str
2129    @property
2130    def hint(self) -> str:
2131        return self.text("hint").upper()
alias_or_name: str
2133    @property
2134    def alias_or_name(self) -> str:
2135        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:
2137    def on(
2138        self,
2139        *expressions: t.Optional[ExpOrStr],
2140        append: bool = True,
2141        dialect: DialectType = None,
2142        copy: bool = True,
2143        **opts,
2144    ) -> Join:
2145        """
2146        Append to or set the ON expressions.
2147
2148        Example:
2149            >>> import sqlglot
2150            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2151            'JOIN x ON y = 1'
2152
2153        Args:
2154            *expressions: the SQL code strings to parse.
2155                If an `Expression` instance is passed, it will be used as-is.
2156                Multiple expressions are combined with an AND operator.
2157            append: if `True`, AND the new expressions to any existing expression.
2158                Otherwise, this resets the expression.
2159            dialect: the dialect used to parse the input expressions.
2160            copy: if `False`, modify this expression instance in-place.
2161            opts: other options to use to parse the input expressions.
2162
2163        Returns:
2164            The modified Join expression.
2165        """
2166        join = _apply_conjunction_builder(
2167            *expressions,
2168            instance=self,
2169            arg="on",
2170            append=append,
2171            dialect=dialect,
2172            copy=copy,
2173            **opts,
2174        )
2175
2176        if join.kind == "CROSS":
2177            join.set("kind", None)
2178
2179        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:
2181    def using(
2182        self,
2183        *expressions: t.Optional[ExpOrStr],
2184        append: bool = True,
2185        dialect: DialectType = None,
2186        copy: bool = True,
2187        **opts,
2188    ) -> Join:
2189        """
2190        Append to or set the USING expressions.
2191
2192        Example:
2193            >>> import sqlglot
2194            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2195            'JOIN x USING (foo, bla)'
2196
2197        Args:
2198            *expressions: the SQL code strings to parse.
2199                If an `Expression` instance is passed, it will be used as-is.
2200            append: if `True`, concatenate the new expressions to the existing "using" list.
2201                Otherwise, this resets the expression.
2202            dialect: the dialect used to parse the input expressions.
2203            copy: if `False`, modify this expression instance in-place.
2204            opts: other options to use to parse the input expressions.
2205
2206        Returns:
2207            The modified Join expression.
2208        """
2209        join = _apply_list_builder(
2210            *expressions,
2211            instance=self,
2212            arg="using",
2213            append=append,
2214            dialect=dialect,
2215            copy=copy,
2216            **opts,
2217        )
2218
2219        if join.kind == "CROSS":
2220            join.set("kind", None)
2221
2222        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):
2225class Lateral(UDTF):
2226    arg_types = {
2227        "this": True,
2228        "view": False,
2229        "outer": False,
2230        "alias": False,
2231        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2232    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2235class MatchRecognizeMeasure(Expression):
2236    arg_types = {
2237        "this": True,
2238        "window_frame": False,
2239    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2242class MatchRecognize(Expression):
2243    arg_types = {
2244        "partition_by": False,
2245        "order": False,
2246        "measures": False,
2247        "rows": False,
2248        "after": False,
2249        "pattern": False,
2250        "define": False,
2251        "alias": False,
2252    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2257class Final(Expression):
2258    pass
key = 'final'
class Offset(Expression):
2261class Offset(Expression):
2262    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2265class Order(Expression):
2266    arg_types = {
2267        "this": False,
2268        "expressions": True,
2269        "interpolate": False,
2270        "siblings": False,
2271    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2275class WithFill(Expression):
2276    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2281class Cluster(Order):
2282    pass
key = 'cluster'
class Distribute(Order):
2285class Distribute(Order):
2286    pass
key = 'distribute'
class Sort(Order):
2289class Sort(Order):
2290    pass
key = 'sort'
class Ordered(Expression):
2293class Ordered(Expression):
2294    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):
2297class Property(Expression):
2298    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2301class AlgorithmProperty(Property):
2302    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2305class AutoIncrementProperty(Property):
2306    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2310class AutoRefreshProperty(Property):
2311    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2314class BackupProperty(Property):
2315    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2318class BlockCompressionProperty(Property):
2319    arg_types = {
2320        "autotemp": False,
2321        "always": False,
2322        "default": False,
2323        "manual": False,
2324        "never": False,
2325    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2328class CharacterSetProperty(Property):
2329    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2332class ChecksumProperty(Property):
2333    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2336class CollateProperty(Property):
2337    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2340class CopyGrantsProperty(Property):
2341    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2344class DataBlocksizeProperty(Property):
2345    arg_types = {
2346        "size": False,
2347        "units": False,
2348        "minimum": False,
2349        "maximum": False,
2350        "default": False,
2351    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2354class DefinerProperty(Property):
2355    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2358class DistKeyProperty(Property):
2359    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2362class DistStyleProperty(Property):
2363    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2366class EngineProperty(Property):
2367    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2370class HeapProperty(Property):
2371    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2374class ToTableProperty(Property):
2375    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2378class ExecuteAsProperty(Property):
2379    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2382class ExternalProperty(Property):
2383    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2386class FallbackProperty(Property):
2387    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2390class FileFormatProperty(Property):
2391    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2394class FreespaceProperty(Property):
2395    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2398class GlobalProperty(Property):
2399    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2402class IcebergProperty(Property):
2403    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2406class InheritsProperty(Property):
2407    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2410class InputModelProperty(Property):
2411    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2414class OutputModelProperty(Property):
2415    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2418class IsolatedLoadingProperty(Property):
2419    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2422class JournalProperty(Property):
2423    arg_types = {
2424        "no": False,
2425        "dual": False,
2426        "before": False,
2427        "local": False,
2428        "after": False,
2429    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2432class LanguageProperty(Property):
2433    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2437class ClusteredByProperty(Property):
2438    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2441class DictProperty(Property):
2442    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2445class DictSubProperty(Property):
2446    pass
key = 'dictsubproperty'
class DictRange(Property):
2449class DictRange(Property):
2450    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2455class OnCluster(Property):
2456    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2459class LikeProperty(Property):
2460    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2463class LocationProperty(Property):
2464    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2467class LockProperty(Property):
2468    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2471class LockingProperty(Property):
2472    arg_types = {
2473        "this": False,
2474        "kind": True,
2475        "for_or_in": False,
2476        "lock_type": True,
2477        "override": False,
2478    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2481class LogProperty(Property):
2482    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2485class MaterializedProperty(Property):
2486    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2489class MergeBlockRatioProperty(Property):
2490    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):
2493class NoPrimaryIndexProperty(Property):
2494    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2497class OnProperty(Property):
2498    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2501class OnCommitProperty(Property):
2502    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2505class PartitionedByProperty(Property):
2506    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2510class PartitionBoundSpec(Expression):
2511    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2512    arg_types = {
2513        "this": False,
2514        "expression": False,
2515        "from_expressions": False,
2516        "to_expressions": False,
2517    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2520class PartitionedOfProperty(Property):
2521    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2522    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2525class RemoteWithConnectionModelProperty(Property):
2526    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2529class ReturnsProperty(Property):
2530    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2533class RowFormatProperty(Property):
2534    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2537class RowFormatDelimitedProperty(Property):
2538    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2539    arg_types = {
2540        "fields": False,
2541        "escaped": False,
2542        "collection_items": False,
2543        "map_keys": False,
2544        "lines": False,
2545        "null": False,
2546        "serde": False,
2547    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2550class RowFormatSerdeProperty(Property):
2551    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2555class QueryTransform(Expression):
2556    arg_types = {
2557        "expressions": True,
2558        "command_script": True,
2559        "schema": False,
2560        "row_format_before": False,
2561        "record_writer": False,
2562        "row_format_after": False,
2563        "record_reader": False,
2564    }
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):
2567class SampleProperty(Property):
2568    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2571class SchemaCommentProperty(Property):
2572    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2575class SerdeProperties(Property):
2576    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2579class SetProperty(Property):
2580    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2583class SharingProperty(Property):
2584    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2587class SetConfigProperty(Property):
2588    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2591class SettingsProperty(Property):
2592    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2595class SortKeyProperty(Property):
2596    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2599class SqlReadWriteProperty(Property):
2600    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2603class SqlSecurityProperty(Property):
2604    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2607class StabilityProperty(Property):
2608    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2611class TemporaryProperty(Property):
2612    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2615class TransformModelProperty(Property):
2616    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2619class TransientProperty(Property):
2620    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2623class UnloggedProperty(Property):
2624    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2628class ViewAttributeProperty(Property):
2629    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2632class VolatileProperty(Property):
2633    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2636class WithDataProperty(Property):
2637    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2640class WithJournalTableProperty(Property):
2641    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2644class WithSystemVersioningProperty(Property):
2645    # this -> history table name, expression -> data consistency check
2646    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2649class Properties(Expression):
2650    arg_types = {"expressions": True}
2651
2652    NAME_TO_PROPERTY = {
2653        "ALGORITHM": AlgorithmProperty,
2654        "AUTO_INCREMENT": AutoIncrementProperty,
2655        "CHARACTER SET": CharacterSetProperty,
2656        "CLUSTERED_BY": ClusteredByProperty,
2657        "COLLATE": CollateProperty,
2658        "COMMENT": SchemaCommentProperty,
2659        "DEFINER": DefinerProperty,
2660        "DISTKEY": DistKeyProperty,
2661        "DISTSTYLE": DistStyleProperty,
2662        "ENGINE": EngineProperty,
2663        "EXECUTE AS": ExecuteAsProperty,
2664        "FORMAT": FileFormatProperty,
2665        "LANGUAGE": LanguageProperty,
2666        "LOCATION": LocationProperty,
2667        "LOCK": LockProperty,
2668        "PARTITIONED_BY": PartitionedByProperty,
2669        "RETURNS": ReturnsProperty,
2670        "ROW_FORMAT": RowFormatProperty,
2671        "SORTKEY": SortKeyProperty,
2672    }
2673
2674    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2675
2676    # CREATE property locations
2677    # Form: schema specified
2678    #   create [POST_CREATE]
2679    #     table a [POST_NAME]
2680    #     (b int) [POST_SCHEMA]
2681    #     with ([POST_WITH])
2682    #     index (b) [POST_INDEX]
2683    #
2684    # Form: alias selection
2685    #   create [POST_CREATE]
2686    #     table a [POST_NAME]
2687    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2688    #     index (c) [POST_INDEX]
2689    class Location(AutoName):
2690        POST_CREATE = auto()
2691        POST_NAME = auto()
2692        POST_SCHEMA = auto()
2693        POST_WITH = auto()
2694        POST_ALIAS = auto()
2695        POST_EXPRESSION = auto()
2696        POST_INDEX = auto()
2697        UNSUPPORTED = auto()
2698
2699    @classmethod
2700    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2701        expressions = []
2702        for key, value in properties_dict.items():
2703            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2704            if property_cls:
2705                expressions.append(property_cls(this=convert(value)))
2706            else:
2707                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2708
2709        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:
2699    @classmethod
2700    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2701        expressions = []
2702        for key, value in properties_dict.items():
2703            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2704            if property_cls:
2705                expressions.append(property_cls(this=convert(value)))
2706            else:
2707                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2708
2709        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2689    class Location(AutoName):
2690        POST_CREATE = auto()
2691        POST_NAME = auto()
2692        POST_SCHEMA = auto()
2693        POST_WITH = auto()
2694        POST_ALIAS = auto()
2695        POST_EXPRESSION = auto()
2696        POST_INDEX = auto()
2697        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):
2712class Qualify(Expression):
2713    pass
key = 'qualify'
class InputOutputFormat(Expression):
2716class InputOutputFormat(Expression):
2717    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2721class Return(Expression):
2722    pass
key = 'return'
class Reference(Expression):
2725class Reference(Expression):
2726    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2729class Tuple(Expression):
2730    arg_types = {"expressions": False}
2731
2732    def isin(
2733        self,
2734        *expressions: t.Any,
2735        query: t.Optional[ExpOrStr] = None,
2736        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2737        copy: bool = True,
2738        **opts,
2739    ) -> In:
2740        return In(
2741            this=maybe_copy(self, copy),
2742            expressions=[convert(e, copy=copy) for e in expressions],
2743            query=maybe_parse(query, copy=copy, **opts) if query else None,
2744            unnest=(
2745                Unnest(
2746                    expressions=[
2747                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2748                        for e in ensure_list(unnest)
2749                    ]
2750                )
2751                if unnest
2752                else None
2753            ),
2754        )
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:
2732    def isin(
2733        self,
2734        *expressions: t.Any,
2735        query: t.Optional[ExpOrStr] = None,
2736        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2737        copy: bool = True,
2738        **opts,
2739    ) -> In:
2740        return In(
2741            this=maybe_copy(self, copy),
2742            expressions=[convert(e, copy=copy) for e in expressions],
2743            query=maybe_parse(query, copy=copy, **opts) if query else None,
2744            unnest=(
2745                Unnest(
2746                    expressions=[
2747                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2748                        for e in ensure_list(unnest)
2749                    ]
2750                )
2751                if unnest
2752                else None
2753            ),
2754        )
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):
2785class QueryOption(Expression):
2786    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2790class WithTableHint(Expression):
2791    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2795class IndexTableHint(Expression):
2796    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2800class HistoricalData(Expression):
2801    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2804class Table(Expression):
2805    arg_types = {
2806        "this": False,
2807        "alias": False,
2808        "db": False,
2809        "catalog": False,
2810        "laterals": False,
2811        "joins": False,
2812        "pivots": False,
2813        "hints": False,
2814        "system_time": False,
2815        "version": False,
2816        "format": False,
2817        "pattern": False,
2818        "ordinality": False,
2819        "when": False,
2820        "only": False,
2821    }
2822
2823    @property
2824    def name(self) -> str:
2825        if isinstance(self.this, Func):
2826            return ""
2827        return self.this.name
2828
2829    @property
2830    def db(self) -> str:
2831        return self.text("db")
2832
2833    @property
2834    def catalog(self) -> str:
2835        return self.text("catalog")
2836
2837    @property
2838    def selects(self) -> t.List[Expression]:
2839        return []
2840
2841    @property
2842    def named_selects(self) -> t.List[str]:
2843        return []
2844
2845    @property
2846    def parts(self) -> t.List[Expression]:
2847        """Return the parts of a table in order catalog, db, table."""
2848        parts: t.List[Expression] = []
2849
2850        for arg in ("catalog", "db", "this"):
2851            part = self.args.get(arg)
2852
2853            if isinstance(part, Dot):
2854                parts.extend(part.flatten())
2855            elif isinstance(part, Expression):
2856                parts.append(part)
2857
2858        return parts
2859
2860    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2861        parts = self.parts
2862        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2863        alias = self.args.get("alias")
2864        if alias:
2865            col = alias_(col, alias.this, copy=copy)
2866        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
2823    @property
2824    def name(self) -> str:
2825        if isinstance(self.this, Func):
2826            return ""
2827        return self.this.name
db: str
2829    @property
2830    def db(self) -> str:
2831        return self.text("db")
catalog: str
2833    @property
2834    def catalog(self) -> str:
2835        return self.text("catalog")
selects: List[Expression]
2837    @property
2838    def selects(self) -> t.List[Expression]:
2839        return []
named_selects: List[str]
2841    @property
2842    def named_selects(self) -> t.List[str]:
2843        return []
parts: List[Expression]
2845    @property
2846    def parts(self) -> t.List[Expression]:
2847        """Return the parts of a table in order catalog, db, table."""
2848        parts: t.List[Expression] = []
2849
2850        for arg in ("catalog", "db", "this"):
2851            part = self.args.get(arg)
2852
2853            if isinstance(part, Dot):
2854                parts.extend(part.flatten())
2855            elif isinstance(part, Expression):
2856                parts.append(part)
2857
2858        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
2898    @property
2899    def is_star(self) -> bool:
2900        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2902    @property
2903    def selects(self) -> t.List[Expression]:
2904        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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:
3192    def limit(
3193        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3194    ) -> Select:
3195        return _apply_builder(
3196            expression=expression,
3197            instance=self,
3198            arg="limit",
3199            into=Limit,
3200            prefix="LIMIT",
3201            dialect=dialect,
3202            copy=copy,
3203            into_arg="expression",
3204            **opts,
3205        )

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3631    @property
3632    def selects(self) -> t.List[Expression]:
3633        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4245class DPipe(Binary):
4246    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4249class EQ(Binary, Predicate):
4250    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4253class NullSafeEQ(Binary, Predicate):
4254    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4257class NullSafeNEQ(Binary, Predicate):
4258    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4262class PropertyEQ(Binary):
4263    pass
key = 'propertyeq'
class Distance(Binary):
4266class Distance(Binary):
4267    pass
key = 'distance'
class Escape(Binary):
4270class Escape(Binary):
4271    pass
key = 'escape'
class Glob(Binary, Predicate):
4274class Glob(Binary, Predicate):
4275    pass
key = 'glob'
class GT(Binary, Predicate):
4278class GT(Binary, Predicate):
4279    pass
key = 'gt'
class GTE(Binary, Predicate):
4282class GTE(Binary, Predicate):
4283    pass
key = 'gte'
class ILike(Binary, Predicate):
4286class ILike(Binary, Predicate):
4287    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4290class ILikeAny(Binary, Predicate):
4291    pass
key = 'ilikeany'
class IntDiv(Binary):
4294class IntDiv(Binary):
4295    pass
key = 'intdiv'
class Is(Binary, Predicate):
4298class Is(Binary, Predicate):
4299    pass
key = 'is'
class Kwarg(Binary):
4302class Kwarg(Binary):
4303    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4306class Like(Binary, Predicate):
4307    pass
key = 'like'
class LikeAny(Binary, Predicate):
4310class LikeAny(Binary, Predicate):
4311    pass
key = 'likeany'
class LT(Binary, Predicate):
4314class LT(Binary, Predicate):
4315    pass
key = 'lt'
class LTE(Binary, Predicate):
4318class LTE(Binary, Predicate):
4319    pass
key = 'lte'
class Mod(Binary):
4322class Mod(Binary):
4323    pass
key = 'mod'
class Mul(Binary):
4326class Mul(Binary):
4327    pass
key = 'mul'
class NEQ(Binary, Predicate):
4330class NEQ(Binary, Predicate):
4331    pass
key = 'neq'
class Operator(Binary):
4335class Operator(Binary):
4336    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4339class SimilarTo(Binary, Predicate):
4340    pass
key = 'similarto'
class Slice(Binary):
4343class Slice(Binary):
4344    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4347class Sub(Binary):
4348    pass
key = 'sub'
class Unary(Condition):
4353class Unary(Condition):
4354    pass
key = 'unary'
class BitwiseNot(Unary):
4357class BitwiseNot(Unary):
4358    pass
key = 'bitwisenot'
class Not(Unary):
4361class Not(Unary):
4362    pass
key = 'not'
class Paren(Unary):
4365class Paren(Unary):
4366    @property
4367    def output_name(self) -> str:
4368        return self.this.name
output_name: str
4366    @property
4367    def output_name(self) -> str:
4368        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):
4371class Neg(Unary):
4372    pass
key = 'neg'
class Alias(Expression):
4375class Alias(Expression):
4376    arg_types = {"this": True, "alias": False}
4377
4378    @property
4379    def output_name(self) -> str:
4380        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4378    @property
4379    def output_name(self) -> str:
4380        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):
4385class PivotAlias(Alias):
4386    pass
key = 'pivotalias'
class Aliases(Expression):
4389class Aliases(Expression):
4390    arg_types = {"this": True, "expressions": True}
4391
4392    @property
4393    def aliases(self):
4394        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4392    @property
4393    def aliases(self):
4394        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4398class AtIndex(Expression):
4399    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4402class AtTimeZone(Expression):
4403    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4406class FromTimeZone(Expression):
4407    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4410class Between(Predicate):
4411    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4414class Bracket(Condition):
4415    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4416    arg_types = {
4417        "this": True,
4418        "expressions": True,
4419        "offset": False,
4420        "safe": False,
4421        "returns_list_for_maps": False,
4422    }
4423
4424    @property
4425    def output_name(self) -> str:
4426        if len(self.expressions) == 1:
4427            return self.expressions[0].output_name
4428
4429        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4424    @property
4425    def output_name(self) -> str:
4426        if len(self.expressions) == 1:
4427            return self.expressions[0].output_name
4428
4429        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):
4432class Distinct(Expression):
4433    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4436class In(Predicate):
4437    arg_types = {
4438        "this": True,
4439        "expressions": False,
4440        "query": False,
4441        "unnest": False,
4442        "field": False,
4443        "is_global": False,
4444    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4448class ForIn(Expression):
4449    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4452class TimeUnit(Expression):
4453    """Automatically converts unit arg into a var."""
4454
4455    arg_types = {"unit": False}
4456
4457    UNABBREVIATED_UNIT_NAME = {
4458        "D": "DAY",
4459        "H": "HOUR",
4460        "M": "MINUTE",
4461        "MS": "MILLISECOND",
4462        "NS": "NANOSECOND",
4463        "Q": "QUARTER",
4464        "S": "SECOND",
4465        "US": "MICROSECOND",
4466        "W": "WEEK",
4467        "Y": "YEAR",
4468    }
4469
4470    VAR_LIKE = (Column, Literal, Var)
4471
4472    def __init__(self, **args):
4473        unit = args.get("unit")
4474        if isinstance(unit, self.VAR_LIKE):
4475            args["unit"] = Var(
4476                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4477            )
4478        elif isinstance(unit, Week):
4479            unit.set("this", Var(this=unit.this.name.upper()))
4480
4481        super().__init__(**args)
4482
4483    @property
4484    def unit(self) -> t.Optional[Var | IntervalSpan]:
4485        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4472    def __init__(self, **args):
4473        unit = args.get("unit")
4474        if isinstance(unit, self.VAR_LIKE):
4475            args["unit"] = Var(
4476                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4477            )
4478        elif isinstance(unit, Week):
4479            unit.set("this", Var(this=unit.this.name.upper()))
4480
4481        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]
4483    @property
4484    def unit(self) -> t.Optional[Var | IntervalSpan]:
4485        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4488class IntervalOp(TimeUnit):
4489    arg_types = {"unit": True, "expression": True}
4490
4491    def interval(self):
4492        return Interval(
4493            this=self.expression.copy(),
4494            unit=self.unit.copy(),
4495        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4491    def interval(self):
4492        return Interval(
4493            this=self.expression.copy(),
4494            unit=self.unit.copy(),
4495        )
key = 'intervalop'
class IntervalSpan(DataType):
4501class IntervalSpan(DataType):
4502    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4505class Interval(TimeUnit):
4506    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4509class IgnoreNulls(Expression):
4510    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4513class RespectNulls(Expression):
4514    pass
key = 'respectnulls'
class HavingMax(Expression):
4518class HavingMax(Expression):
4519    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4523class Func(Condition):
4524    """
4525    The base class for all function expressions.
4526
4527    Attributes:
4528        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4529            treated as a variable length argument and the argument's value will be stored as a list.
4530        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4531            function expression. These values are used to map this node to a name during parsing as
4532            well as to provide the function's name during SQL string generation. By default the SQL
4533            name is set to the expression's class name transformed to snake case.
4534    """
4535
4536    is_var_len_args = False
4537
4538    @classmethod
4539    def from_arg_list(cls, args):
4540        if cls.is_var_len_args:
4541            all_arg_keys = list(cls.arg_types)
4542            # If this function supports variable length argument treat the last argument as such.
4543            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4544            num_non_var = len(non_var_len_arg_keys)
4545
4546            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4547            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4548        else:
4549            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4550
4551        return cls(**args_dict)
4552
4553    @classmethod
4554    def sql_names(cls):
4555        if cls is Func:
4556            raise NotImplementedError(
4557                "SQL name is only supported by concrete function implementations"
4558            )
4559        if "_sql_names" not in cls.__dict__:
4560            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4561        return cls._sql_names
4562
4563    @classmethod
4564    def sql_name(cls):
4565        return cls.sql_names()[0]
4566
4567    @classmethod
4568    def default_parser_mappings(cls):
4569        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):
4538    @classmethod
4539    def from_arg_list(cls, args):
4540        if cls.is_var_len_args:
4541            all_arg_keys = list(cls.arg_types)
4542            # If this function supports variable length argument treat the last argument as such.
4543            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4544            num_non_var = len(non_var_len_arg_keys)
4545
4546            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4547            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4548        else:
4549            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4550
4551        return cls(**args_dict)
@classmethod
def sql_names(cls):
4553    @classmethod
4554    def sql_names(cls):
4555        if cls is Func:
4556            raise NotImplementedError(
4557                "SQL name is only supported by concrete function implementations"
4558            )
4559        if "_sql_names" not in cls.__dict__:
4560            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4561        return cls._sql_names
@classmethod
def sql_name(cls):
4563    @classmethod
4564    def sql_name(cls):
4565        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4567    @classmethod
4568    def default_parser_mappings(cls):
4569        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4572class AggFunc(Func):
4573    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4576class ParameterizedAgg(AggFunc):
4577    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4580class Abs(Func):
4581    pass
key = 'abs'
class ArgMax(AggFunc):
4584class ArgMax(AggFunc):
4585    arg_types = {"this": True, "expression": True, "count": False}
4586    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4589class ArgMin(AggFunc):
4590    arg_types = {"this": True, "expression": True, "count": False}
4591    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4594class ApproxTopK(AggFunc):
4595    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4598class Flatten(Func):
4599    pass
key = 'flatten'
class Transform(Func):
4603class Transform(Func):
4604    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4607class Anonymous(Func):
4608    arg_types = {"this": True, "expressions": False}
4609    is_var_len_args = True
4610
4611    @property
4612    def name(self) -> str:
4613        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
4611    @property
4612    def name(self) -> str:
4613        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4616class AnonymousAggFunc(AggFunc):
4617    arg_types = {"this": True, "expressions": False}
4618    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4622class CombinedAggFunc(AnonymousAggFunc):
4623    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4626class CombinedParameterizedAgg(ParameterizedAgg):
4627    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):
4632class Hll(AggFunc):
4633    arg_types = {"this": True, "expressions": False}
4634    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4637class ApproxDistinct(AggFunc):
4638    arg_types = {"this": True, "accuracy": False}
4639    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4642class Array(Func):
4643    arg_types = {"expressions": False}
4644    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4648class ToArray(Func):
4649    pass
key = 'toarray'
class ToChar(Func):
4654class ToChar(Func):
4655    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4660class ToNumber(Func):
4661    arg_types = {
4662        "this": True,
4663        "format": False,
4664        "nlsparam": False,
4665        "precision": False,
4666        "scale": False,
4667    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4671class Convert(Func):
4672    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4675class GenerateSeries(Func):
4676    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):
4679class ArrayAgg(AggFunc):
4680    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4683class ArrayUniqueAgg(AggFunc):
4684    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4687class ArrayAll(Func):
4688    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4692class ArrayAny(Func):
4693    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4696class ArrayConcat(Func):
4697    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4698    arg_types = {"this": True, "expressions": False}
4699    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4702class ArrayContains(Binary, Func):
4703    pass
key = 'arraycontains'
class ArrayContained(Binary):
4706class ArrayContained(Binary):
4707    pass
key = 'arraycontained'
class ArrayFilter(Func):
4710class ArrayFilter(Func):
4711    arg_types = {"this": True, "expression": True}
4712    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4715class ArrayToString(Func):
4716    arg_types = {"this": True, "expression": True, "null": False}
4717    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4720class ArrayOverlaps(Binary, Func):
4721    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4724class ArraySize(Func):
4725    arg_types = {"this": True, "expression": False}
4726    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4729class ArraySort(Func):
4730    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4733class ArraySum(Func):
4734    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4737class ArrayUnionAgg(AggFunc):
4738    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4741class Avg(AggFunc):
4742    pass
key = 'avg'
class AnyValue(AggFunc):
4745class AnyValue(AggFunc):
4746    pass
key = 'anyvalue'
class Lag(AggFunc):
4749class Lag(AggFunc):
4750    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4753class Lead(AggFunc):
4754    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4759class First(AggFunc):
4760    pass
key = 'first'
class Last(AggFunc):
4763class Last(AggFunc):
4764    pass
key = 'last'
class FirstValue(AggFunc):
4767class FirstValue(AggFunc):
4768    pass
key = 'firstvalue'
class LastValue(AggFunc):
4771class LastValue(AggFunc):
4772    pass
key = 'lastvalue'
class NthValue(AggFunc):
4775class NthValue(AggFunc):
4776    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4779class Case(Func):
4780    arg_types = {"this": False, "ifs": True, "default": False}
4781
4782    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4783        instance = maybe_copy(self, copy)
4784        instance.append(
4785            "ifs",
4786            If(
4787                this=maybe_parse(condition, copy=copy, **opts),
4788                true=maybe_parse(then, copy=copy, **opts),
4789            ),
4790        )
4791        return instance
4792
4793    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4794        instance = maybe_copy(self, copy)
4795        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4796        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:
4782    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4783        instance = maybe_copy(self, copy)
4784        instance.append(
4785            "ifs",
4786            If(
4787                this=maybe_parse(condition, copy=copy, **opts),
4788                true=maybe_parse(then, copy=copy, **opts),
4789            ),
4790        )
4791        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4793    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4794        instance = maybe_copy(self, copy)
4795        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4796        return instance
key = 'case'
class Cast(Func):
4799class Cast(Func):
4800    arg_types = {
4801        "this": True,
4802        "to": True,
4803        "format": False,
4804        "safe": False,
4805        "action": False,
4806    }
4807
4808    @property
4809    def name(self) -> str:
4810        return self.this.name
4811
4812    @property
4813    def to(self) -> DataType:
4814        return self.args["to"]
4815
4816    @property
4817    def output_name(self) -> str:
4818        return self.name
4819
4820    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4821        """
4822        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4823        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4824        array<int> != array<float>.
4825
4826        Args:
4827            dtypes: the data types to compare this Cast's DataType to.
4828
4829        Returns:
4830            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4831        """
4832        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4808    @property
4809    def name(self) -> str:
4810        return self.this.name
to: DataType
4812    @property
4813    def to(self) -> DataType:
4814        return self.args["to"]
output_name: str
4816    @property
4817    def output_name(self) -> str:
4818        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:
4820    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4821        """
4822        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4823        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4824        array<int> != array<float>.
4825
4826        Args:
4827            dtypes: the data types to compare this Cast's DataType to.
4828
4829        Returns:
4830            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4831        """
4832        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):
4835class TryCast(Cast):
4836    pass
key = 'trycast'
class CastToStrType(Func):
4839class CastToStrType(Func):
4840    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4843class Collate(Binary, Func):
4844    pass
key = 'collate'
class Ceil(Func):
4847class Ceil(Func):
4848    arg_types = {"this": True, "decimals": False}
4849    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4852class Coalesce(Func):
4853    arg_types = {"this": True, "expressions": False}
4854    is_var_len_args = True
4855    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4858class Chr(Func):
4859    arg_types = {"this": True, "charset": False, "expressions": False}
4860    is_var_len_args = True
4861    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4864class Concat(Func):
4865    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4866    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4869class ConcatWs(Concat):
4870    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4874class ConnectByRoot(Func):
4875    pass
key = 'connectbyroot'
class Count(AggFunc):
4878class Count(AggFunc):
4879    arg_types = {"this": False, "expressions": False}
4880    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4883class CountIf(AggFunc):
4884    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4888class Cbrt(Func):
4889    pass
key = 'cbrt'
class CurrentDate(Func):
4892class CurrentDate(Func):
4893    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4896class CurrentDatetime(Func):
4897    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4900class CurrentTime(Func):
4901    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4904class CurrentTimestamp(Func):
4905    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4908class CurrentUser(Func):
4909    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4912class DateAdd(Func, IntervalOp):
4913    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4916class DateSub(Func, IntervalOp):
4917    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4920class DateDiff(Func, TimeUnit):
4921    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4922    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4925class DateTrunc(Func):
4926    arg_types = {"unit": True, "this": True, "zone": False}
4927
4928    def __init__(self, **args):
4929        unit = args.get("unit")
4930        if isinstance(unit, TimeUnit.VAR_LIKE):
4931            args["unit"] = Literal.string(
4932                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4933            )
4934        elif isinstance(unit, Week):
4935            unit.set("this", Literal.string(unit.this.name.upper()))
4936
4937        super().__init__(**args)
4938
4939    @property
4940    def unit(self) -> Expression:
4941        return self.args["unit"]
DateTrunc(**args)
4928    def __init__(self, **args):
4929        unit = args.get("unit")
4930        if isinstance(unit, TimeUnit.VAR_LIKE):
4931            args["unit"] = Literal.string(
4932                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4933            )
4934        elif isinstance(unit, Week):
4935            unit.set("this", Literal.string(unit.this.name.upper()))
4936
4937        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4939    @property
4940    def unit(self) -> Expression:
4941        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4944class DatetimeAdd(Func, IntervalOp):
4945    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4948class DatetimeSub(Func, IntervalOp):
4949    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4952class DatetimeDiff(Func, TimeUnit):
4953    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4956class DatetimeTrunc(Func, TimeUnit):
4957    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4960class DayOfWeek(Func):
4961    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4964class DayOfMonth(Func):
4965    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4968class DayOfYear(Func):
4969    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4972class ToDays(Func):
4973    pass
key = 'todays'
class WeekOfYear(Func):
4976class WeekOfYear(Func):
4977    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4980class MonthsBetween(Func):
4981    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4984class LastDay(Func, TimeUnit):
4985    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4986    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4989class Extract(Func):
4990    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4993class Timestamp(Func):
4994    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4997class TimestampAdd(Func, TimeUnit):
4998    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5001class TimestampSub(Func, TimeUnit):
5002    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5005class TimestampDiff(Func, TimeUnit):
5006    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5007    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5010class TimestampTrunc(Func, TimeUnit):
5011    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5014class TimeAdd(Func, TimeUnit):
5015    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5018class TimeSub(Func, TimeUnit):
5019    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5022class TimeDiff(Func, TimeUnit):
5023    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5026class TimeTrunc(Func, TimeUnit):
5027    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5030class DateFromParts(Func):
5031    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5032    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5035class TimeFromParts(Func):
5036    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5037    arg_types = {
5038        "hour": True,
5039        "min": True,
5040        "sec": True,
5041        "nano": False,
5042        "fractions": False,
5043        "precision": False,
5044    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5047class DateStrToDate(Func):
5048    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5051class DateToDateStr(Func):
5052    pass
key = 'datetodatestr'
class DateToDi(Func):
5055class DateToDi(Func):
5056    pass
key = 'datetodi'
class Date(Func):
5060class Date(Func):
5061    arg_types = {"this": False, "zone": False, "expressions": False}
5062    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5065class Day(Func):
5066    pass
key = 'day'
class Decode(Func):
5069class Decode(Func):
5070    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5073class DiToDate(Func):
5074    pass
key = 'ditodate'
class Encode(Func):
5077class Encode(Func):
5078    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5081class Exp(Func):
5082    pass
key = 'exp'
class Explode(Func):
5086class Explode(Func):
5087    arg_types = {"this": True, "expressions": False}
5088    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5091class ExplodeOuter(Explode):
5092    pass
key = 'explodeouter'
class Posexplode(Explode):
5095class Posexplode(Explode):
5096    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5099class PosexplodeOuter(Posexplode, ExplodeOuter):
5100    pass
key = 'posexplodeouter'
class Floor(Func):
5103class Floor(Func):
5104    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5107class FromBase64(Func):
5108    pass
key = 'frombase64'
class ToBase64(Func):
5111class ToBase64(Func):
5112    pass
key = 'tobase64'
class GenerateDateArray(Func):
5115class GenerateDateArray(Func):
5116    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5119class Greatest(Func):
5120    arg_types = {"this": True, "expressions": False}
5121    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5124class GroupConcat(AggFunc):
5125    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5128class Hex(Func):
5129    pass
key = 'hex'
class Xor(Connector, Func):
5132class Xor(Connector, Func):
5133    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5136class If(Func):
5137    arg_types = {"this": True, "true": True, "false": False}
5138    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5141class Nullif(Func):
5142    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5145class Initcap(Func):
5146    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5149class IsNan(Func):
5150    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5153class IsInf(Func):
5154    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5157class JSONPath(Expression):
5158    arg_types = {"expressions": True}
5159
5160    @property
5161    def output_name(self) -> str:
5162        last_segment = self.expressions[-1].this
5163        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5160    @property
5161    def output_name(self) -> str:
5162        last_segment = self.expressions[-1].this
5163        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):
5166class JSONPathPart(Expression):
5167    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5170class JSONPathFilter(JSONPathPart):
5171    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5174class JSONPathKey(JSONPathPart):
5175    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5178class JSONPathRecursive(JSONPathPart):
5179    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5182class JSONPathRoot(JSONPathPart):
5183    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5186class JSONPathScript(JSONPathPart):
5187    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5190class JSONPathSlice(JSONPathPart):
5191    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5194class JSONPathSelector(JSONPathPart):
5195    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5198class JSONPathSubscript(JSONPathPart):
5199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5202class JSONPathUnion(JSONPathPart):
5203    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5206class JSONPathWildcard(JSONPathPart):
5207    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5210class FormatJson(Expression):
5211    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5214class JSONKeyValue(Expression):
5215    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5218class JSONObject(Func):
5219    arg_types = {
5220        "expressions": False,
5221        "null_handling": False,
5222        "unique_keys": False,
5223        "return_type": False,
5224        "encoding": False,
5225    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5228class JSONObjectAgg(AggFunc):
5229    arg_types = {
5230        "expressions": False,
5231        "null_handling": False,
5232        "unique_keys": False,
5233        "return_type": False,
5234        "encoding": False,
5235    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5239class JSONArray(Func):
5240    arg_types = {
5241        "expressions": True,
5242        "null_handling": False,
5243        "return_type": False,
5244        "strict": False,
5245    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5249class JSONArrayAgg(Func):
5250    arg_types = {
5251        "this": True,
5252        "order": False,
5253        "null_handling": False,
5254        "return_type": False,
5255        "strict": False,
5256    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5261class JSONColumnDef(Expression):
5262    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):
5265class JSONSchema(Expression):
5266    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5270class JSONTable(Func):
5271    arg_types = {
5272        "this": True,
5273        "schema": True,
5274        "path": False,
5275        "error_handling": False,
5276        "empty_handling": False,
5277    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5280class OpenJSONColumnDef(Expression):
5281    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):
5284class OpenJSON(Func):
5285    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5288class JSONBContains(Binary):
5289    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5292class JSONExtract(Binary, Func):
5293    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5294    _sql_names = ["JSON_EXTRACT"]
5295    is_var_len_args = True
5296
5297    @property
5298    def output_name(self) -> str:
5299        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
5297    @property
5298    def output_name(self) -> str:
5299        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):
5302class JSONExtractScalar(Binary, Func):
5303    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5304    _sql_names = ["JSON_EXTRACT_SCALAR"]
5305    is_var_len_args = True
5306
5307    @property
5308    def output_name(self) -> str:
5309        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
5307    @property
5308    def output_name(self) -> str:
5309        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):
5312class JSONBExtract(Binary, Func):
5313    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5316class JSONBExtractScalar(Binary, Func):
5317    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5320class JSONFormat(Func):
5321    arg_types = {"this": False, "options": False}
5322    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5326class JSONArrayContains(Binary, Predicate, Func):
5327    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5330class ParseJSON(Func):
5331    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5332    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5333    arg_types = {"this": True, "expressions": False}
5334    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5337class Least(Func):
5338    arg_types = {"this": True, "expressions": False}
5339    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5342class Left(Func):
5343    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5350class Length(Func):
5351    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5354class Levenshtein(Func):
5355    arg_types = {
5356        "this": True,
5357        "expression": False,
5358        "ins_cost": False,
5359        "del_cost": False,
5360        "sub_cost": False,
5361    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5364class Ln(Func):
5365    pass
key = 'ln'
class Log(Func):
5368class Log(Func):
5369    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5372class LogicalOr(AggFunc):
5373    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5376class LogicalAnd(AggFunc):
5377    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5380class Lower(Func):
5381    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5384class Map(Func):
5385    arg_types = {"keys": False, "values": False}
5386
5387    @property
5388    def keys(self) -> t.List[Expression]:
5389        keys = self.args.get("keys")
5390        return keys.expressions if keys else []
5391
5392    @property
5393    def values(self) -> t.List[Expression]:
5394        values = self.args.get("values")
5395        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5387    @property
5388    def keys(self) -> t.List[Expression]:
5389        keys = self.args.get("keys")
5390        return keys.expressions if keys else []
values: List[Expression]
5392    @property
5393    def values(self) -> t.List[Expression]:
5394        values = self.args.get("values")
5395        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5399class ToMap(Func):
5400    pass
key = 'tomap'
class MapFromEntries(Func):
5403class MapFromEntries(Func):
5404    pass
key = 'mapfromentries'
class StarMap(Func):
5407class StarMap(Func):
5408    pass
key = 'starmap'
class VarMap(Func):
5411class VarMap(Func):
5412    arg_types = {"keys": True, "values": True}
5413    is_var_len_args = True
5414
5415    @property
5416    def keys(self) -> t.List[Expression]:
5417        return self.args["keys"].expressions
5418
5419    @property
5420    def values(self) -> t.List[Expression]:
5421        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5415    @property
5416    def keys(self) -> t.List[Expression]:
5417        return self.args["keys"].expressions
values: List[Expression]
5419    @property
5420    def values(self) -> t.List[Expression]:
5421        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5425class MatchAgainst(Func):
5426    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5429class Max(AggFunc):
5430    arg_types = {"this": True, "expressions": False}
5431    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5434class MD5(Func):
5435    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5439class MD5Digest(Func):
5440    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5443class Min(AggFunc):
5444    arg_types = {"this": True, "expressions": False}
5445    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5448class Month(Func):
5449    pass
key = 'month'
class AddMonths(Func):
5452class AddMonths(Func):
5453    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5456class Nvl2(Func):
5457    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5461class Predict(Func):
5462    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5465class Pow(Binary, Func):
5466    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5469class PercentileCont(AggFunc):
5470    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5473class PercentileDisc(AggFunc):
5474    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5477class Quantile(AggFunc):
5478    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5481class ApproxQuantile(Quantile):
5482    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):
5485class Rand(Func):
5486    _sql_names = ["RAND", "RANDOM"]
5487    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5490class Randn(Func):
5491    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5494class RangeN(Func):
5495    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5498class ReadCSV(Func):
5499    _sql_names = ["READ_CSV"]
5500    is_var_len_args = True
5501    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5504class Reduce(Func):
5505    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):
5508class RegexpExtract(Func):
5509    arg_types = {
5510        "this": True,
5511        "expression": True,
5512        "position": False,
5513        "occurrence": False,
5514        "parameters": False,
5515        "group": False,
5516    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5519class RegexpReplace(Func):
5520    arg_types = {
5521        "this": True,
5522        "expression": True,
5523        "replacement": False,
5524        "position": False,
5525        "occurrence": False,
5526        "parameters": False,
5527        "modifiers": False,
5528    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5531class RegexpLike(Binary, Func):
5532    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5535class RegexpILike(Binary, Func):
5536    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5541class RegexpSplit(Func):
5542    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5545class Repeat(Func):
5546    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5551class Round(Func):
5552    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5555class RowNumber(Func):
5556    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5559class SafeDivide(Func):
5560    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5563class SHA(Func):
5564    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5567class SHA2(Func):
5568    _sql_names = ["SHA2"]
5569    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5572class Sign(Func):
5573    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5576class SortArray(Func):
5577    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5580class Split(Func):
5581    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5586class Substring(Func):
5587    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5590class StandardHash(Func):
5591    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5594class StartsWith(Func):
5595    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5596    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5599class StrPosition(Func):
5600    arg_types = {
5601        "this": True,
5602        "substr": True,
5603        "position": False,
5604        "instance": False,
5605    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5608class StrToDate(Func):
5609    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5612class StrToTime(Func):
5613    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5618class StrToUnix(Func):
5619    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5624class StrToMap(Func):
5625    arg_types = {
5626        "this": True,
5627        "pair_delim": False,
5628        "key_value_delim": False,
5629        "duplicate_resolution_callback": False,
5630    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5633class NumberToStr(Func):
5634    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5637class FromBase(Func):
5638    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5641class Struct(Func):
5642    arg_types = {"expressions": False}
5643    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5646class StructExtract(Func):
5647    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5652class Stuff(Func):
5653    _sql_names = ["STUFF", "INSERT"]
5654    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):
5657class Sum(AggFunc):
5658    pass
key = 'sum'
class Sqrt(Func):
5661class Sqrt(Func):
5662    pass
key = 'sqrt'
class Stddev(AggFunc):
5665class Stddev(AggFunc):
5666    pass
key = 'stddev'
class StddevPop(AggFunc):
5669class StddevPop(AggFunc):
5670    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5673class StddevSamp(AggFunc):
5674    pass
key = 'stddevsamp'
class TimeToStr(Func):
5677class TimeToStr(Func):
5678    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5681class TimeToTimeStr(Func):
5682    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5685class TimeToUnix(Func):
5686    pass
key = 'timetounix'
class TimeStrToDate(Func):
5689class TimeStrToDate(Func):
5690    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5693class TimeStrToTime(Func):
5694    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5697class TimeStrToUnix(Func):
5698    pass
key = 'timestrtounix'
class Trim(Func):
5701class Trim(Func):
5702    arg_types = {
5703        "this": True,
5704        "expression": False,
5705        "position": False,
5706        "collation": False,
5707    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5710class TsOrDsAdd(Func, TimeUnit):
5711    # return_type is used to correctly cast the arguments of this expression when transpiling it
5712    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5713
5714    @property
5715    def return_type(self) -> DataType:
5716        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
5714    @property
5715    def return_type(self) -> DataType:
5716        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5719class TsOrDsDiff(Func, TimeUnit):
5720    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5723class TsOrDsToDateStr(Func):
5724    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5727class TsOrDsToDate(Func):
5728    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5731class TsOrDsToTime(Func):
5732    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5735class TsOrDsToTimestamp(Func):
5736    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5739class TsOrDiToDi(Func):
5740    pass
key = 'tsorditodi'
class Unhex(Func):
5743class Unhex(Func):
5744    pass
key = 'unhex'
class UnixDate(Func):
5748class UnixDate(Func):
5749    pass
key = 'unixdate'
class UnixToStr(Func):
5752class UnixToStr(Func):
5753    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5758class UnixToTime(Func):
5759    arg_types = {
5760        "this": True,
5761        "scale": False,
5762        "zone": False,
5763        "hours": False,
5764        "minutes": False,
5765        "format": False,
5766    }
5767
5768    SECONDS = Literal.number(0)
5769    DECIS = Literal.number(1)
5770    CENTIS = Literal.number(2)
5771    MILLIS = Literal.number(3)
5772    DECIMILLIS = Literal.number(4)
5773    CENTIMILLIS = Literal.number(5)
5774    MICROS = Literal.number(6)
5775    DECIMICROS = Literal.number(7)
5776    CENTIMICROS = Literal.number(8)
5777    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):
5780class UnixToTimeStr(Func):
5781    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5784class TimestampFromParts(Func):
5785    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5786    arg_types = {
5787        "year": True,
5788        "month": True,
5789        "day": True,
5790        "hour": True,
5791        "min": True,
5792        "sec": True,
5793        "nano": False,
5794        "zone": False,
5795        "milli": False,
5796    }
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):
5799class Upper(Func):
5800    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5803class Corr(Binary, AggFunc):
5804    pass
key = 'corr'
class Variance(AggFunc):
5807class Variance(AggFunc):
5808    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5811class VariancePop(AggFunc):
5812    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5815class CovarSamp(Binary, AggFunc):
5816    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5819class CovarPop(Binary, AggFunc):
5820    pass
key = 'covarpop'
class Week(Func):
5823class Week(Func):
5824    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5827class XMLTable(Func):
5828    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):
5831class Year(Func):
5832    pass
key = 'year'
class Use(Expression):
5835class Use(Expression):
5836    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5839class Merge(Expression):
5840    arg_types = {
5841        "this": True,
5842        "using": True,
5843        "on": True,
5844        "expressions": True,
5845        "with": False,
5846    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5849class When(Func):
5850    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):
5855class NextValueFor(Func):
5856    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:
5894def maybe_parse(
5895    sql_or_expression: ExpOrStr,
5896    *,
5897    into: t.Optional[IntoType] = None,
5898    dialect: DialectType = None,
5899    prefix: t.Optional[str] = None,
5900    copy: bool = False,
5901    **opts,
5902) -> Expression:
5903    """Gracefully handle a possible string or expression.
5904
5905    Example:
5906        >>> maybe_parse("1")
5907        Literal(this=1, is_string=False)
5908        >>> maybe_parse(to_identifier("x"))
5909        Identifier(this=x, quoted=False)
5910
5911    Args:
5912        sql_or_expression: the SQL code string or an expression
5913        into: the SQLGlot Expression to parse into
5914        dialect: the dialect used to parse the input expressions (in the case that an
5915            input expression is a SQL string).
5916        prefix: a string to prefix the sql with before it gets parsed
5917            (automatically includes a space)
5918        copy: whether to copy the expression.
5919        **opts: other options to use to parse the input expressions (again, in the case
5920            that an input expression is a SQL string).
5921
5922    Returns:
5923        Expression: the parsed or given expression.
5924    """
5925    if isinstance(sql_or_expression, Expression):
5926        if copy:
5927            return sql_or_expression.copy()
5928        return sql_or_expression
5929
5930    if sql_or_expression is None:
5931        raise ParseError("SQL cannot be None")
5932
5933    import sqlglot
5934
5935    sql = str(sql_or_expression)
5936    if prefix:
5937        sql = f"{prefix} {sql}"
5938
5939    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):
5950def maybe_copy(instance, copy=True):
5951    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:
6165def union(
6166    left: ExpOrStr,
6167    right: ExpOrStr,
6168    distinct: bool = True,
6169    dialect: DialectType = None,
6170    copy: bool = True,
6171    **opts,
6172) -> Union:
6173    """
6174    Initializes a syntax tree from one UNION expression.
6175
6176    Example:
6177        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6178        'SELECT * FROM foo UNION SELECT * FROM bla'
6179
6180    Args:
6181        left: the SQL code string corresponding to the left-hand side.
6182            If an `Expression` instance is passed, it will be used as-is.
6183        right: the SQL code string corresponding to the right-hand side.
6184            If an `Expression` instance is passed, it will be used as-is.
6185        distinct: set the DISTINCT flag if and only if this is true.
6186        dialect: the dialect used to parse the input expression.
6187        copy: whether to copy the expression.
6188        opts: other options to use to parse the input expressions.
6189
6190    Returns:
6191        The new Union instance.
6192    """
6193    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6194    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6195
6196    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:
6199def intersect(
6200    left: ExpOrStr,
6201    right: ExpOrStr,
6202    distinct: bool = True,
6203    dialect: DialectType = None,
6204    copy: bool = True,
6205    **opts,
6206) -> Intersect:
6207    """
6208    Initializes a syntax tree from one INTERSECT expression.
6209
6210    Example:
6211        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6212        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6213
6214    Args:
6215        left: the SQL code string corresponding to the left-hand side.
6216            If an `Expression` instance is passed, it will be used as-is.
6217        right: the SQL code string corresponding to the right-hand side.
6218            If an `Expression` instance is passed, it will be used as-is.
6219        distinct: set the DISTINCT flag if and only if this is true.
6220        dialect: the dialect used to parse the input expression.
6221        copy: whether to copy the expression.
6222        opts: other options to use to parse the input expressions.
6223
6224    Returns:
6225        The new Intersect instance.
6226    """
6227    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6228    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6229
6230    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:
6233def except_(
6234    left: ExpOrStr,
6235    right: ExpOrStr,
6236    distinct: bool = True,
6237    dialect: DialectType = None,
6238    copy: bool = True,
6239    **opts,
6240) -> Except:
6241    """
6242    Initializes a syntax tree from one EXCEPT expression.
6243
6244    Example:
6245        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6246        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6247
6248    Args:
6249        left: the SQL code string corresponding to the left-hand side.
6250            If an `Expression` instance is passed, it will be used as-is.
6251        right: the SQL code string corresponding to the right-hand side.
6252            If an `Expression` instance is passed, it will be used as-is.
6253        distinct: set the DISTINCT flag if and only if this is true.
6254        dialect: the dialect used to parse the input expression.
6255        copy: whether to copy the expression.
6256        opts: other options to use to parse the input expressions.
6257
6258    Returns:
6259        The new Except instance.
6260    """
6261    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6262    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6263
6264    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:
6267def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6268    """
6269    Initializes a syntax tree from one or multiple SELECT expressions.
6270
6271    Example:
6272        >>> select("col1", "col2").from_("tbl").sql()
6273        'SELECT col1, col2 FROM tbl'
6274
6275    Args:
6276        *expressions: the SQL code string to parse as the expressions of a
6277            SELECT statement. If an Expression instance is passed, this is used as-is.
6278        dialect: the dialect used to parse the input expressions (in the case that an
6279            input expression is a SQL string).
6280        **opts: other options to use to parse the input expressions (again, in the case
6281            that an input expression is a SQL string).
6282
6283    Returns:
6284        Select: the syntax tree for the SELECT statement.
6285    """
6286    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:
6289def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6290    """
6291    Initializes a syntax tree from a FROM expression.
6292
6293    Example:
6294        >>> from_("tbl").select("col1", "col2").sql()
6295        'SELECT col1, col2 FROM tbl'
6296
6297    Args:
6298        *expression: the SQL code string to parse as the FROM expressions of a
6299            SELECT statement. If an Expression instance is passed, this is used as-is.
6300        dialect: the dialect used to parse the input expression (in the case that the
6301            input expression is a SQL string).
6302        **opts: other options to use to parse the input expressions (again, in the case
6303            that the input expression is a SQL string).
6304
6305    Returns:
6306        Select: the syntax tree for the SELECT statement.
6307    """
6308    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:
6311def update(
6312    table: str | Table,
6313    properties: dict,
6314    where: t.Optional[ExpOrStr] = None,
6315    from_: t.Optional[ExpOrStr] = None,
6316    dialect: DialectType = None,
6317    **opts,
6318) -> Update:
6319    """
6320    Creates an update statement.
6321
6322    Example:
6323        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6324        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6325
6326    Args:
6327        *properties: dictionary of properties to set which are
6328            auto converted to sql objects eg None -> NULL
6329        where: sql conditional parsed into a WHERE statement
6330        from_: sql statement parsed into a FROM statement
6331        dialect: the dialect used to parse the input expressions.
6332        **opts: other options to use to parse the input expressions.
6333
6334    Returns:
6335        Update: the syntax tree for the UPDATE statement.
6336    """
6337    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6338    update_expr.set(
6339        "expressions",
6340        [
6341            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6342            for k, v in properties.items()
6343        ],
6344    )
6345    if from_:
6346        update_expr.set(
6347            "from",
6348            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6349        )
6350    if isinstance(where, Condition):
6351        where = Where(this=where)
6352    if where:
6353        update_expr.set(
6354            "where",
6355            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6356        )
6357    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:
6360def delete(
6361    table: ExpOrStr,
6362    where: t.Optional[ExpOrStr] = None,
6363    returning: t.Optional[ExpOrStr] = None,
6364    dialect: DialectType = None,
6365    **opts,
6366) -> Delete:
6367    """
6368    Builds a delete statement.
6369
6370    Example:
6371        >>> delete("my_table", where="id > 1").sql()
6372        'DELETE FROM my_table WHERE id > 1'
6373
6374    Args:
6375        where: sql conditional parsed into a WHERE statement
6376        returning: sql conditional parsed into a RETURNING statement
6377        dialect: the dialect used to parse the input expressions.
6378        **opts: other options to use to parse the input expressions.
6379
6380    Returns:
6381        Delete: the syntax tree for the DELETE statement.
6382    """
6383    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6384    if where:
6385        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6386    if returning:
6387        delete_expr = t.cast(
6388            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6389        )
6390    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:
6393def insert(
6394    expression: ExpOrStr,
6395    into: ExpOrStr,
6396    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6397    overwrite: t.Optional[bool] = None,
6398    returning: t.Optional[ExpOrStr] = None,
6399    dialect: DialectType = None,
6400    copy: bool = True,
6401    **opts,
6402) -> Insert:
6403    """
6404    Builds an INSERT statement.
6405
6406    Example:
6407        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6408        'INSERT INTO tbl VALUES (1, 2, 3)'
6409
6410    Args:
6411        expression: the sql string or expression of the INSERT statement
6412        into: the tbl to insert data to.
6413        columns: optionally the table's column names.
6414        overwrite: whether to INSERT OVERWRITE or not.
6415        returning: sql conditional parsed into a RETURNING statement
6416        dialect: the dialect used to parse the input expressions.
6417        copy: whether to copy the expression.
6418        **opts: other options to use to parse the input expressions.
6419
6420    Returns:
6421        Insert: the syntax tree for the INSERT statement.
6422    """
6423    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6424    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6425
6426    if columns:
6427        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6428
6429    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6430
6431    if returning:
6432        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6433
6434    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:
6437def condition(
6438    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6439) -> Condition:
6440    """
6441    Initialize a logical condition expression.
6442
6443    Example:
6444        >>> condition("x=1").sql()
6445        'x = 1'
6446
6447        This is helpful for composing larger logical syntax trees:
6448        >>> where = condition("x=1")
6449        >>> where = where.and_("y=1")
6450        >>> Select().from_("tbl").select("*").where(where).sql()
6451        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6452
6453    Args:
6454        *expression: the SQL code string to parse.
6455            If an Expression instance is passed, this is used as-is.
6456        dialect: the dialect used to parse the input expression (in the case that the
6457            input expression is a SQL string).
6458        copy: Whether to copy `expression` (only applies to expressions).
6459        **opts: other options to use to parse the input expressions (again, in the case
6460            that the input expression is a SQL string).
6461
6462    Returns:
6463        The new Condition instance
6464    """
6465    return maybe_parse(
6466        expression,
6467        into=Condition,
6468        dialect=dialect,
6469        copy=copy,
6470        **opts,
6471    )

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

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:
6647def to_table(
6648    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6649) -> Table:
6650    """
6651    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6652    If a table is passed in then that table is returned.
6653
6654    Args:
6655        sql_path: a `[catalog].[schema].[table]` string.
6656        dialect: the source dialect according to which the table name will be parsed.
6657        copy: Whether to copy a table if it is passed in.
6658        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6659
6660    Returns:
6661        A table expression.
6662    """
6663    if isinstance(sql_path, Table):
6664        return maybe_copy(sql_path, copy=copy)
6665
6666    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6667
6668    for k, v in kwargs.items():
6669        table.set(k, v)
6670
6671    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6674def to_column(
6675    sql_path: str | Column,
6676    quoted: t.Optional[bool] = None,
6677    dialect: DialectType = None,
6678    copy: bool = True,
6679    **kwargs,
6680) -> Column:
6681    """
6682    Create a column from a `[table].[column]` sql path. Table is optional.
6683    If a column is passed in then that column is returned.
6684
6685    Args:
6686        sql_path: a `[table].[column]` string.
6687        quoted: Whether or not to force quote identifiers.
6688        dialect: the source dialect according to which the column name will be parsed.
6689        copy: Whether to copy a column if it is passed in.
6690        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6691
6692    Returns:
6693        A column expression.
6694    """
6695    if isinstance(sql_path, Column):
6696        return maybe_copy(sql_path, copy=copy)
6697
6698    try:
6699        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6700    except ParseError:
6701        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6702
6703    for k, v in kwargs.items():
6704        col.set(k, v)
6705
6706    if quoted:
6707        for i in col.find_all(Identifier):
6708            i.set("quoted", True)
6709
6710    return col

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

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

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6713def alias_(
6714    expression: ExpOrStr,
6715    alias: t.Optional[str | Identifier],
6716    table: bool | t.Sequence[str | Identifier] = False,
6717    quoted: t.Optional[bool] = None,
6718    dialect: DialectType = None,
6719    copy: bool = True,
6720    **opts,
6721):
6722    """Create an Alias expression.
6723
6724    Example:
6725        >>> alias_('foo', 'bar').sql()
6726        'foo AS bar'
6727
6728        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6729        '(SELECT 1, 2) AS bar(a, b)'
6730
6731    Args:
6732        expression: the SQL code strings to parse.
6733            If an Expression instance is passed, this is used as-is.
6734        alias: the alias name to use. If the name has
6735            special characters it is quoted.
6736        table: Whether to create a table alias, can also be a list of columns.
6737        quoted: whether to quote the alias
6738        dialect: the dialect used to parse the input expression.
6739        copy: Whether to copy the expression.
6740        **opts: other options to use to parse the input expressions.
6741
6742    Returns:
6743        Alias: the aliased expression
6744    """
6745    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6746    alias = to_identifier(alias, quoted=quoted)
6747
6748    if table:
6749        table_alias = TableAlias(this=alias)
6750        exp.set("alias", table_alias)
6751
6752        if not isinstance(table, bool):
6753            for column in table:
6754                table_alias.append("columns", to_identifier(column, quoted=quoted))
6755
6756        return exp
6757
6758    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6759    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6760    # for the complete Window expression.
6761    #
6762    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6763
6764    if "alias" in exp.arg_types and not isinstance(exp, Window):
6765        exp.set("alias", alias)
6766        return exp
6767    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:
6770def subquery(
6771    expression: ExpOrStr,
6772    alias: t.Optional[Identifier | str] = None,
6773    dialect: DialectType = None,
6774    **opts,
6775) -> Select:
6776    """
6777    Build a subquery expression that's selected from.
6778
6779    Example:
6780        >>> subquery('select x from tbl', 'bar').select('x').sql()
6781        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6782
6783    Args:
6784        expression: the SQL code strings to parse.
6785            If an Expression instance is passed, this is used as-is.
6786        alias: the alias name to use.
6787        dialect: the dialect used to parse the input expression.
6788        **opts: other options to use to parse the input expressions.
6789
6790    Returns:
6791        A new Select instance with the subquery expression included.
6792    """
6793
6794    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6795    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):
6826def column(
6827    col,
6828    table=None,
6829    db=None,
6830    catalog=None,
6831    *,
6832    fields=None,
6833    quoted=None,
6834    copy=True,
6835):
6836    """
6837    Build a Column.
6838
6839    Args:
6840        col: Column name.
6841        table: Table name.
6842        db: Database name.
6843        catalog: Catalog name.
6844        fields: Additional fields using dots.
6845        quoted: Whether to force quotes on the column's identifiers.
6846        copy: Whether to copy identifiers if passed in.
6847
6848    Returns:
6849        The new Column instance.
6850    """
6851    this = Column(
6852        this=to_identifier(col, quoted=quoted, copy=copy),
6853        table=to_identifier(table, quoted=quoted, copy=copy),
6854        db=to_identifier(db, quoted=quoted, copy=copy),
6855        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6856    )
6857
6858    if fields:
6859        this = Dot.build(
6860            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
6861        )
6862    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:
6865def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6866    """Cast an expression to a data type.
6867
6868    Example:
6869        >>> cast('x + 1', 'int').sql()
6870        'CAST(x + 1 AS INT)'
6871
6872    Args:
6873        expression: The expression to cast.
6874        to: The datatype to cast to.
6875        copy: Whether to copy the supplied expressions.
6876
6877    Returns:
6878        The new Cast instance.
6879    """
6880    expression = maybe_parse(expression, copy=copy, **opts)
6881    data_type = DataType.build(to, copy=copy, **opts)
6882    expression = Cast(this=expression, to=data_type)
6883    expression.type = data_type
6884    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:
6887def table_(
6888    table: Identifier | str,
6889    db: t.Optional[Identifier | str] = None,
6890    catalog: t.Optional[Identifier | str] = None,
6891    quoted: t.Optional[bool] = None,
6892    alias: t.Optional[Identifier | str] = None,
6893) -> Table:
6894    """Build a Table.
6895
6896    Args:
6897        table: Table name.
6898        db: Database name.
6899        catalog: Catalog name.
6900        quote: Whether to force quotes on the table's identifiers.
6901        alias: Table's alias.
6902
6903    Returns:
6904        The new Table instance.
6905    """
6906    return Table(
6907        this=to_identifier(table, quoted=quoted) if table else None,
6908        db=to_identifier(db, quoted=quoted) if db else None,
6909        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6910        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6911    )

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

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

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

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

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

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

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

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

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:
7488def true() -> Boolean:
7489    """
7490    Returns a true Boolean expression.
7491    """
7492    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7495def false() -> Boolean:
7496    """
7497    Returns a false Boolean expression.
7498    """
7499    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7502def null() -> Null:
7503    """
7504    Returns a Null expression.
7505    """
7506    return Null()

Returns a Null expression.

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