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

the generator object.

def dfs( self, 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 (function): 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 (bool): 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 (function): a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy (bool): if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

def replace(self, expression):
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, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1341class Kill(Expression):
1342    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1345class Pragma(Expression):
1346    pass
key = 'pragma'
class Set(Expression):
1349class Set(Expression):
1350    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1353class Heredoc(Expression):
1354    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1357class SetItem(Expression):
1358    arg_types = {
1359        "this": False,
1360        "expressions": False,
1361        "kind": False,
1362        "collate": False,  # MySQL SET NAMES statement
1363        "global": False,
1364    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1367class Show(Expression):
1368    arg_types = {
1369        "this": True,
1370        "history": False,
1371        "terse": False,
1372        "target": False,
1373        "offset": False,
1374        "starts_with": False,
1375        "limit": False,
1376        "from": False,
1377        "like": False,
1378        "where": False,
1379        "db": False,
1380        "scope": False,
1381        "scope_kind": False,
1382        "full": False,
1383        "mutex": False,
1384        "query": False,
1385        "channel": False,
1386        "global": False,
1387        "log": False,
1388        "position": False,
1389        "types": False,
1390    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1393class UserDefinedFunction(Expression):
1394    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1397class CharacterSet(Expression):
1398    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1401class With(Expression):
1402    arg_types = {"expressions": True, "recursive": False}
1403
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1404    @property
1405    def recursive(self) -> bool:
1406        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1409class WithinGroup(Expression):
1410    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1415class CTE(DerivedTable):
1416    arg_types = {
1417        "this": True,
1418        "alias": True,
1419        "scalar": False,
1420        "materialized": False,
1421    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class TableAlias(Expression):
1424class TableAlias(Expression):
1425    arg_types = {"this": False, "columns": False}
1426
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1427    @property
1428    def columns(self):
1429        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1432class BitString(Condition):
1433    pass
key = 'bitstring'
class HexString(Condition):
1436class HexString(Condition):
1437    pass
key = 'hexstring'
class ByteString(Condition):
1440class ByteString(Condition):
1441    pass
key = 'bytestring'
class RawString(Condition):
1444class RawString(Condition):
1445    pass
key = 'rawstring'
class UnicodeString(Condition):
1448class UnicodeString(Condition):
1449    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1452class Column(Condition):
1453    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1454
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
1458
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
1462
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
1466
1467    @property
1468    def output_name(self) -> str:
1469        return self.name
1470
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]
1479
1480    def to_dot(self) -> Dot | Identifier:
1481        """Converts the column into a dot expression."""
1482        parts = self.parts
1483        parent = self.parent
1484
1485        while parent:
1486            if isinstance(parent, Dot):
1487                parts.append(parent.expression)
1488            parent = parent.parent
1489
1490        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1455    @property
1456    def table(self) -> str:
1457        return self.text("table")
db: str
1459    @property
1460    def db(self) -> str:
1461        return self.text("db")
catalog: str
1463    @property
1464    def catalog(self) -> str:
1465        return self.text("catalog")
output_name: str
1467    @property
1468    def output_name(self) -> str:
1469        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1471    @property
1472    def parts(self) -> t.List[Identifier]:
1473        """Return the parts of a column in order catalog, db, table, name."""
1474        return [
1475            t.cast(Identifier, self.args[part])
1476            for part in ("catalog", "db", "table", "this")
1477            if self.args.get(part)
1478        ]

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

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

Converts the column into a dot expression.

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

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

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):
1819class Drop(Expression):
1820    arg_types = {
1821        "this": False,
1822        "kind": False,
1823        "expressions": False,
1824        "exists": False,
1825        "temporary": False,
1826        "materialized": False,
1827        "cascade": False,
1828        "constraints": False,
1829        "purge": False,
1830    }
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):
1833class Filter(Expression):
1834    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1837class Check(Expression):
1838    pass
key = 'check'
class Connect(Expression):
1842class Connect(Expression):
1843    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1846class Prior(Expression):
1847    pass
key = 'prior'
class Directory(Expression):
1850class Directory(Expression):
1851    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1852    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1855class ForeignKey(Expression):
1856    arg_types = {
1857        "expressions": True,
1858        "reference": False,
1859        "delete": False,
1860        "update": False,
1861    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1864class ColumnPrefix(Expression):
1865    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1868class PrimaryKey(Expression):
1869    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1874class Into(Expression):
1875    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1878class From(Expression):
1879    @property
1880    def name(self) -> str:
1881        return self.this.name
1882
1883    @property
1884    def alias_or_name(self) -> str:
1885        return self.this.alias_or_name
name: str
1879    @property
1880    def name(self) -> str:
1881        return self.this.name
alias_or_name: str
1883    @property
1884    def alias_or_name(self) -> str:
1885        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1888class Having(Expression):
1889    pass
key = 'having'
class Hint(Expression):
1892class Hint(Expression):
1893    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1896class JoinHint(Expression):
1897    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1900class Identifier(Expression):
1901    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1902
1903    @property
1904    def quoted(self) -> bool:
1905        return bool(self.args.get("quoted"))
1906
1907    @property
1908    def hashable_args(self) -> t.Any:
1909        return (self.this, self.quoted)
1910
1911    @property
1912    def output_name(self) -> str:
1913        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1903    @property
1904    def quoted(self) -> bool:
1905        return bool(self.args.get("quoted"))
hashable_args: Any
1907    @property
1908    def hashable_args(self) -> t.Any:
1909        return (self.this, self.quoted)
output_name: str
1911    @property
1912    def output_name(self) -> str:
1913        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):
1917class Opclass(Expression):
1918    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1921class Index(Expression):
1922    arg_types = {
1923        "this": False,
1924        "table": False,
1925        "unique": False,
1926        "primary": False,
1927        "amp": False,  # teradata
1928        "params": False,
1929    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
1932class IndexParameters(Expression):
1933    arg_types = {
1934        "using": False,
1935        "include": False,
1936        "columns": False,
1937        "with_storage": False,
1938        "partition_by": False,
1939        "tablespace": False,
1940        "where": False,
1941    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
1944class Insert(DDL, DML):
1945    arg_types = {
1946        "hint": False,
1947        "with": False,
1948        "is_function": False,
1949        "this": True,
1950        "expression": False,
1951        "conflict": False,
1952        "returning": False,
1953        "overwrite": False,
1954        "exists": False,
1955        "partition": False,
1956        "alternative": False,
1957        "where": False,
1958        "ignore": False,
1959        "by_name": False,
1960    }
1961
1962    def with_(
1963        self,
1964        alias: ExpOrStr,
1965        as_: ExpOrStr,
1966        recursive: t.Optional[bool] = None,
1967        append: bool = True,
1968        dialect: DialectType = None,
1969        copy: bool = True,
1970        **opts,
1971    ) -> Insert:
1972        """
1973        Append to or set the common table expressions.
1974
1975        Example:
1976            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1977            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1978
1979        Args:
1980            alias: the SQL code string to parse as the table name.
1981                If an `Expression` instance is passed, this is used as-is.
1982            as_: the SQL code string to parse as the table expression.
1983                If an `Expression` instance is passed, it will be used as-is.
1984            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1985            append: if `True`, add to any existing expressions.
1986                Otherwise, this resets the expressions.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            The modified expression.
1993        """
1994        return _apply_cte_builder(
1995            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1996        )
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:
1962    def with_(
1963        self,
1964        alias: ExpOrStr,
1965        as_: ExpOrStr,
1966        recursive: t.Optional[bool] = None,
1967        append: bool = True,
1968        dialect: DialectType = None,
1969        copy: bool = True,
1970        **opts,
1971    ) -> Insert:
1972        """
1973        Append to or set the common table expressions.
1974
1975        Example:
1976            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1977            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1978
1979        Args:
1980            alias: the SQL code string to parse as the table name.
1981                If an `Expression` instance is passed, this is used as-is.
1982            as_: the SQL code string to parse as the table expression.
1983                If an `Expression` instance is passed, it will be used as-is.
1984            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1985            append: if `True`, add to any existing expressions.
1986                Otherwise, this resets the expressions.
1987            dialect: the dialect used to parse the input expression.
1988            copy: if `False`, modify this expression instance in-place.
1989            opts: other options to use to parse the input expressions.
1990
1991        Returns:
1992            The modified expression.
1993        """
1994        return _apply_cte_builder(
1995            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1996        )

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):
1999class OnConflict(Expression):
2000    arg_types = {
2001        "duplicate": False,
2002        "expressions": False,
2003        "action": False,
2004        "conflict_keys": False,
2005        "constraint": False,
2006    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2009class Returning(Expression):
2010    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2014class Introducer(Expression):
2015    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2019class National(Expression):
2020    pass
key = 'national'
class LoadData(Expression):
2023class LoadData(Expression):
2024    arg_types = {
2025        "this": True,
2026        "local": False,
2027        "overwrite": False,
2028        "inpath": True,
2029        "partition": False,
2030        "input_format": False,
2031        "serde": False,
2032    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2035class Partition(Expression):
2036    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2039class PartitionRange(Expression):
2040    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class Fetch(Expression):
2043class Fetch(Expression):
2044    arg_types = {
2045        "direction": False,
2046        "count": False,
2047        "percent": False,
2048        "with_ties": False,
2049    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2052class Group(Expression):
2053    arg_types = {
2054        "expressions": False,
2055        "grouping_sets": False,
2056        "cube": False,
2057        "rollup": False,
2058        "totals": False,
2059        "all": False,
2060    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2063class Lambda(Expression):
2064    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2067class Limit(Expression):
2068    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):
2071class Literal(Condition):
2072    arg_types = {"this": True, "is_string": True}
2073
2074    @property
2075    def hashable_args(self) -> t.Any:
2076        return (self.this, self.args.get("is_string"))
2077
2078    @classmethod
2079    def number(cls, number) -> Literal:
2080        return cls(this=str(number), is_string=False)
2081
2082    @classmethod
2083    def string(cls, string) -> Literal:
2084        return cls(this=str(string), is_string=True)
2085
2086    @property
2087    def output_name(self) -> str:
2088        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2074    @property
2075    def hashable_args(self) -> t.Any:
2076        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2078    @classmethod
2079    def number(cls, number) -> Literal:
2080        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2082    @classmethod
2083    def string(cls, string) -> Literal:
2084        return cls(this=str(string), is_string=True)
output_name: str
2086    @property
2087    def output_name(self) -> str:
2088        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):
2091class Join(Expression):
2092    arg_types = {
2093        "this": True,
2094        "on": False,
2095        "side": False,
2096        "kind": False,
2097        "using": False,
2098        "method": False,
2099        "global": False,
2100        "hint": False,
2101    }
2102
2103    @property
2104    def method(self) -> str:
2105        return self.text("method").upper()
2106
2107    @property
2108    def kind(self) -> str:
2109        return self.text("kind").upper()
2110
2111    @property
2112    def side(self) -> str:
2113        return self.text("side").upper()
2114
2115    @property
2116    def hint(self) -> str:
2117        return self.text("hint").upper()
2118
2119    @property
2120    def alias_or_name(self) -> str:
2121        return self.this.alias_or_name
2122
2123    def on(
2124        self,
2125        *expressions: t.Optional[ExpOrStr],
2126        append: bool = True,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Join:
2131        """
2132        Append to or set the ON expressions.
2133
2134        Example:
2135            >>> import sqlglot
2136            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2137            'JOIN x ON y = 1'
2138
2139        Args:
2140            *expressions: the SQL code strings to parse.
2141                If an `Expression` instance is passed, it will be used as-is.
2142                Multiple expressions are combined with an AND operator.
2143            append: if `True`, AND the new expressions to any existing expression.
2144                Otherwise, this resets the expression.
2145            dialect: the dialect used to parse the input expressions.
2146            copy: if `False`, modify this expression instance in-place.
2147            opts: other options to use to parse the input expressions.
2148
2149        Returns:
2150            The modified Join expression.
2151        """
2152        join = _apply_conjunction_builder(
2153            *expressions,
2154            instance=self,
2155            arg="on",
2156            append=append,
2157            dialect=dialect,
2158            copy=copy,
2159            **opts,
2160        )
2161
2162        if join.kind == "CROSS":
2163            join.set("kind", None)
2164
2165        return join
2166
2167    def using(
2168        self,
2169        *expressions: t.Optional[ExpOrStr],
2170        append: bool = True,
2171        dialect: DialectType = None,
2172        copy: bool = True,
2173        **opts,
2174    ) -> Join:
2175        """
2176        Append to or set the USING expressions.
2177
2178        Example:
2179            >>> import sqlglot
2180            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2181            'JOIN x USING (foo, bla)'
2182
2183        Args:
2184            *expressions: the SQL code strings to parse.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            append: if `True`, concatenate the new expressions to the existing "using" list.
2187                Otherwise, this resets the expression.
2188            dialect: the dialect used to parse the input expressions.
2189            copy: if `False`, modify this expression instance in-place.
2190            opts: other options to use to parse the input expressions.
2191
2192        Returns:
2193            The modified Join expression.
2194        """
2195        join = _apply_list_builder(
2196            *expressions,
2197            instance=self,
2198            arg="using",
2199            append=append,
2200            dialect=dialect,
2201            copy=copy,
2202            **opts,
2203        )
2204
2205        if join.kind == "CROSS":
2206            join.set("kind", None)
2207
2208        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
2103    @property
2104    def method(self) -> str:
2105        return self.text("method").upper()
kind: str
2107    @property
2108    def kind(self) -> str:
2109        return self.text("kind").upper()
side: str
2111    @property
2112    def side(self) -> str:
2113        return self.text("side").upper()
hint: str
2115    @property
2116    def hint(self) -> str:
2117        return self.text("hint").upper()
alias_or_name: str
2119    @property
2120    def alias_or_name(self) -> str:
2121        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:
2123    def on(
2124        self,
2125        *expressions: t.Optional[ExpOrStr],
2126        append: bool = True,
2127        dialect: DialectType = None,
2128        copy: bool = True,
2129        **opts,
2130    ) -> Join:
2131        """
2132        Append to or set the ON expressions.
2133
2134        Example:
2135            >>> import sqlglot
2136            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2137            'JOIN x ON y = 1'
2138
2139        Args:
2140            *expressions: the SQL code strings to parse.
2141                If an `Expression` instance is passed, it will be used as-is.
2142                Multiple expressions are combined with an AND operator.
2143            append: if `True`, AND the new expressions to any existing expression.
2144                Otherwise, this resets the expression.
2145            dialect: the dialect used to parse the input expressions.
2146            copy: if `False`, modify this expression instance in-place.
2147            opts: other options to use to parse the input expressions.
2148
2149        Returns:
2150            The modified Join expression.
2151        """
2152        join = _apply_conjunction_builder(
2153            *expressions,
2154            instance=self,
2155            arg="on",
2156            append=append,
2157            dialect=dialect,
2158            copy=copy,
2159            **opts,
2160        )
2161
2162        if join.kind == "CROSS":
2163            join.set("kind", None)
2164
2165        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:
2167    def using(
2168        self,
2169        *expressions: t.Optional[ExpOrStr],
2170        append: bool = True,
2171        dialect: DialectType = None,
2172        copy: bool = True,
2173        **opts,
2174    ) -> Join:
2175        """
2176        Append to or set the USING expressions.
2177
2178        Example:
2179            >>> import sqlglot
2180            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2181            'JOIN x USING (foo, bla)'
2182
2183        Args:
2184            *expressions: the SQL code strings to parse.
2185                If an `Expression` instance is passed, it will be used as-is.
2186            append: if `True`, concatenate the new expressions to the existing "using" list.
2187                Otherwise, this resets the expression.
2188            dialect: the dialect used to parse the input expressions.
2189            copy: if `False`, modify this expression instance in-place.
2190            opts: other options to use to parse the input expressions.
2191
2192        Returns:
2193            The modified Join expression.
2194        """
2195        join = _apply_list_builder(
2196            *expressions,
2197            instance=self,
2198            arg="using",
2199            append=append,
2200            dialect=dialect,
2201            copy=copy,
2202            **opts,
2203        )
2204
2205        if join.kind == "CROSS":
2206            join.set("kind", None)
2207
2208        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):
2211class Lateral(UDTF):
2212    arg_types = {
2213        "this": True,
2214        "view": False,
2215        "outer": False,
2216        "alias": False,
2217        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2218    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
2221class MatchRecognize(Expression):
2222    arg_types = {
2223        "partition_by": False,
2224        "order": False,
2225        "measures": False,
2226        "rows": False,
2227        "after": False,
2228        "pattern": False,
2229        "define": False,
2230        "alias": False,
2231    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2236class Final(Expression):
2237    pass
key = 'final'
class Offset(Expression):
2240class Offset(Expression):
2241    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2244class Order(Expression):
2245    arg_types = {
2246        "this": False,
2247        "expressions": True,
2248        "interpolate": False,
2249        "siblings": False,
2250    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2254class WithFill(Expression):
2255    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2260class Cluster(Order):
2261    pass
key = 'cluster'
class Distribute(Order):
2264class Distribute(Order):
2265    pass
key = 'distribute'
class Sort(Order):
2268class Sort(Order):
2269    pass
key = 'sort'
class Ordered(Expression):
2272class Ordered(Expression):
2273    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):
2276class Property(Expression):
2277    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2280class AlgorithmProperty(Property):
2281    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2284class AutoIncrementProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2289class AutoRefreshProperty(Property):
2290    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2293class BackupProperty(Property):
2294    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2297class BlockCompressionProperty(Property):
2298    arg_types = {
2299        "autotemp": False,
2300        "always": False,
2301        "default": False,
2302        "manual": False,
2303        "never": False,
2304    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2307class CharacterSetProperty(Property):
2308    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2311class ChecksumProperty(Property):
2312    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2315class CollateProperty(Property):
2316    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2319class CopyGrantsProperty(Property):
2320    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2323class DataBlocksizeProperty(Property):
2324    arg_types = {
2325        "size": False,
2326        "units": False,
2327        "minimum": False,
2328        "maximum": False,
2329        "default": False,
2330    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2333class DefinerProperty(Property):
2334    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2337class DistKeyProperty(Property):
2338    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2341class DistStyleProperty(Property):
2342    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2345class EngineProperty(Property):
2346    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2349class HeapProperty(Property):
2350    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2353class ToTableProperty(Property):
2354    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2357class ExecuteAsProperty(Property):
2358    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2361class ExternalProperty(Property):
2362    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2365class FallbackProperty(Property):
2366    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2369class FileFormatProperty(Property):
2370    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2373class FreespaceProperty(Property):
2374    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2377class GlobalProperty(Property):
2378    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2381class IcebergProperty(Property):
2382    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2385class InheritsProperty(Property):
2386    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2389class InputModelProperty(Property):
2390    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2393class OutputModelProperty(Property):
2394    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2397class IsolatedLoadingProperty(Property):
2398    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2401class JournalProperty(Property):
2402    arg_types = {
2403        "no": False,
2404        "dual": False,
2405        "before": False,
2406        "local": False,
2407        "after": False,
2408    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2411class LanguageProperty(Property):
2412    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2416class ClusteredByProperty(Property):
2417    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2420class DictProperty(Property):
2421    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2424class DictSubProperty(Property):
2425    pass
key = 'dictsubproperty'
class DictRange(Property):
2428class DictRange(Property):
2429    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2434class OnCluster(Property):
2435    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2438class LikeProperty(Property):
2439    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2442class LocationProperty(Property):
2443    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2446class LockProperty(Property):
2447    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2450class LockingProperty(Property):
2451    arg_types = {
2452        "this": False,
2453        "kind": True,
2454        "for_or_in": False,
2455        "lock_type": True,
2456        "override": False,
2457    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2460class LogProperty(Property):
2461    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2464class MaterializedProperty(Property):
2465    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2468class MergeBlockRatioProperty(Property):
2469    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):
2472class NoPrimaryIndexProperty(Property):
2473    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2476class OnProperty(Property):
2477    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2480class OnCommitProperty(Property):
2481    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2484class PartitionedByProperty(Property):
2485    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2489class PartitionBoundSpec(Expression):
2490    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2491    arg_types = {
2492        "this": False,
2493        "expression": False,
2494        "from_expressions": False,
2495        "to_expressions": False,
2496    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2499class PartitionedOfProperty(Property):
2500    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2501    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2504class RemoteWithConnectionModelProperty(Property):
2505    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2508class ReturnsProperty(Property):
2509    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2512class RowFormatProperty(Property):
2513    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2516class RowFormatDelimitedProperty(Property):
2517    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2518    arg_types = {
2519        "fields": False,
2520        "escaped": False,
2521        "collection_items": False,
2522        "map_keys": False,
2523        "lines": False,
2524        "null": False,
2525        "serde": False,
2526    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2529class RowFormatSerdeProperty(Property):
2530    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2534class QueryTransform(Expression):
2535    arg_types = {
2536        "expressions": True,
2537        "command_script": True,
2538        "schema": False,
2539        "row_format_before": False,
2540        "record_writer": False,
2541        "row_format_after": False,
2542        "record_reader": False,
2543    }
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):
2546class SampleProperty(Property):
2547    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2550class SchemaCommentProperty(Property):
2551    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2554class SerdeProperties(Property):
2555    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2558class SetProperty(Property):
2559    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2562class SharingProperty(Property):
2563    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2566class SetConfigProperty(Property):
2567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2570class SettingsProperty(Property):
2571    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2574class SortKeyProperty(Property):
2575    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2578class SqlReadWriteProperty(Property):
2579    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2582class SqlSecurityProperty(Property):
2583    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2586class StabilityProperty(Property):
2587    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2590class TemporaryProperty(Property):
2591    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2594class TransformModelProperty(Property):
2595    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2598class TransientProperty(Property):
2599    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2602class UnloggedProperty(Property):
2603    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2607class ViewAttributeProperty(Property):
2608    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2611class VolatileProperty(Property):
2612    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2615class WithDataProperty(Property):
2616    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2619class WithJournalTableProperty(Property):
2620    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2623class WithSystemVersioningProperty(Property):
2624    # this -> history table name, expression -> data consistency check
2625    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2628class Properties(Expression):
2629    arg_types = {"expressions": True}
2630
2631    NAME_TO_PROPERTY = {
2632        "ALGORITHM": AlgorithmProperty,
2633        "AUTO_INCREMENT": AutoIncrementProperty,
2634        "CHARACTER SET": CharacterSetProperty,
2635        "CLUSTERED_BY": ClusteredByProperty,
2636        "COLLATE": CollateProperty,
2637        "COMMENT": SchemaCommentProperty,
2638        "DEFINER": DefinerProperty,
2639        "DISTKEY": DistKeyProperty,
2640        "DISTSTYLE": DistStyleProperty,
2641        "ENGINE": EngineProperty,
2642        "EXECUTE AS": ExecuteAsProperty,
2643        "FORMAT": FileFormatProperty,
2644        "LANGUAGE": LanguageProperty,
2645        "LOCATION": LocationProperty,
2646        "LOCK": LockProperty,
2647        "PARTITIONED_BY": PartitionedByProperty,
2648        "RETURNS": ReturnsProperty,
2649        "ROW_FORMAT": RowFormatProperty,
2650        "SORTKEY": SortKeyProperty,
2651    }
2652
2653    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2654
2655    # CREATE property locations
2656    # Form: schema specified
2657    #   create [POST_CREATE]
2658    #     table a [POST_NAME]
2659    #     (b int) [POST_SCHEMA]
2660    #     with ([POST_WITH])
2661    #     index (b) [POST_INDEX]
2662    #
2663    # Form: alias selection
2664    #   create [POST_CREATE]
2665    #     table a [POST_NAME]
2666    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2667    #     index (c) [POST_INDEX]
2668    class Location(AutoName):
2669        POST_CREATE = auto()
2670        POST_NAME = auto()
2671        POST_SCHEMA = auto()
2672        POST_WITH = auto()
2673        POST_ALIAS = auto()
2674        POST_EXPRESSION = auto()
2675        POST_INDEX = auto()
2676        UNSUPPORTED = auto()
2677
2678    @classmethod
2679    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2680        expressions = []
2681        for key, value in properties_dict.items():
2682            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2683            if property_cls:
2684                expressions.append(property_cls(this=convert(value)))
2685            else:
2686                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2687
2688        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:
2678    @classmethod
2679    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2680        expressions = []
2681        for key, value in properties_dict.items():
2682            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2683            if property_cls:
2684                expressions.append(property_cls(this=convert(value)))
2685            else:
2686                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2687
2688        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2668    class Location(AutoName):
2669        POST_CREATE = auto()
2670        POST_NAME = auto()
2671        POST_SCHEMA = auto()
2672        POST_WITH = auto()
2673        POST_ALIAS = auto()
2674        POST_EXPRESSION = auto()
2675        POST_INDEX = auto()
2676        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):
2691class Qualify(Expression):
2692    pass
key = 'qualify'
class InputOutputFormat(Expression):
2695class InputOutputFormat(Expression):
2696    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2700class Return(Expression):
2701    pass
key = 'return'
class Reference(Expression):
2704class Reference(Expression):
2705    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2708class Tuple(Expression):
2709    arg_types = {"expressions": False}
2710
2711    def isin(
2712        self,
2713        *expressions: t.Any,
2714        query: t.Optional[ExpOrStr] = None,
2715        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2716        copy: bool = True,
2717        **opts,
2718    ) -> In:
2719        return In(
2720            this=maybe_copy(self, copy),
2721            expressions=[convert(e, copy=copy) for e in expressions],
2722            query=maybe_parse(query, copy=copy, **opts) if query else None,
2723            unnest=(
2724                Unnest(
2725                    expressions=[
2726                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2727                        for e in ensure_list(unnest)
2728                    ]
2729                )
2730                if unnest
2731                else None
2732            ),
2733        )
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:
2711    def isin(
2712        self,
2713        *expressions: t.Any,
2714        query: t.Optional[ExpOrStr] = None,
2715        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2716        copy: bool = True,
2717        **opts,
2718    ) -> In:
2719        return In(
2720            this=maybe_copy(self, copy),
2721            expressions=[convert(e, copy=copy) for e in expressions],
2722            query=maybe_parse(query, copy=copy, **opts) if query else None,
2723            unnest=(
2724                Unnest(
2725                    expressions=[
2726                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2727                        for e in ensure_list(unnest)
2728                    ]
2729                )
2730                if unnest
2731                else None
2732            ),
2733        )
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):
2764class QueryOption(Expression):
2765    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2769class WithTableHint(Expression):
2770    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2774class IndexTableHint(Expression):
2775    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2779class HistoricalData(Expression):
2780    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2783class Table(Expression):
2784    arg_types = {
2785        "this": False,
2786        "alias": False,
2787        "db": False,
2788        "catalog": False,
2789        "laterals": False,
2790        "joins": False,
2791        "pivots": False,
2792        "hints": False,
2793        "system_time": False,
2794        "version": False,
2795        "format": False,
2796        "pattern": False,
2797        "ordinality": False,
2798        "when": False,
2799        "only": False,
2800    }
2801
2802    @property
2803    def name(self) -> str:
2804        if isinstance(self.this, Func):
2805            return ""
2806        return self.this.name
2807
2808    @property
2809    def db(self) -> str:
2810        return self.text("db")
2811
2812    @property
2813    def catalog(self) -> str:
2814        return self.text("catalog")
2815
2816    @property
2817    def selects(self) -> t.List[Expression]:
2818        return []
2819
2820    @property
2821    def named_selects(self) -> t.List[str]:
2822        return []
2823
2824    @property
2825    def parts(self) -> t.List[Expression]:
2826        """Return the parts of a table in order catalog, db, table."""
2827        parts: t.List[Expression] = []
2828
2829        for arg in ("catalog", "db", "this"):
2830            part = self.args.get(arg)
2831
2832            if isinstance(part, Dot):
2833                parts.extend(part.flatten())
2834            elif isinstance(part, Expression):
2835                parts.append(part)
2836
2837        return parts
2838
2839    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2840        parts = self.parts
2841        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2842        alias = self.args.get("alias")
2843        if alias:
2844            col = alias_(col, alias.this, copy=copy)
2845        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
2802    @property
2803    def name(self) -> str:
2804        if isinstance(self.this, Func):
2805            return ""
2806        return self.this.name
db: str
2808    @property
2809    def db(self) -> str:
2810        return self.text("db")
catalog: str
2812    @property
2813    def catalog(self) -> str:
2814        return self.text("catalog")
selects: List[Expression]
2816    @property
2817    def selects(self) -> t.List[Expression]:
2818        return []
named_selects: List[str]
2820    @property
2821    def named_selects(self) -> t.List[str]:
2822        return []
parts: List[Expression]
2824    @property
2825    def parts(self) -> t.List[Expression]:
2826        """Return the parts of a table in order catalog, db, table."""
2827        parts: t.List[Expression] = []
2828
2829        for arg in ("catalog", "db", "this"):
2830            part = self.args.get(arg)
2831
2832            if isinstance(part, Dot):
2833                parts.extend(part.flatten())
2834            elif isinstance(part, Expression):
2835                parts.append(part)
2836
2837        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2839    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2840        parts = self.parts
2841        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2842        alias = self.args.get("alias")
2843        if alias:
2844            col = alias_(col, alias.this, copy=copy)
2845        return col
key = 'table'
class Union(Query):
2848class Union(Query):
2849    arg_types = {
2850        "with": False,
2851        "this": True,
2852        "expression": True,
2853        "distinct": False,
2854        "by_name": False,
2855        **QUERY_MODIFIERS,
2856    }
2857
2858    def select(
2859        self,
2860        *expressions: t.Optional[ExpOrStr],
2861        append: bool = True,
2862        dialect: DialectType = None,
2863        copy: bool = True,
2864        **opts,
2865    ) -> Union:
2866        this = maybe_copy(self, copy)
2867        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2868        this.expression.unnest().select(
2869            *expressions, append=append, dialect=dialect, copy=False, **opts
2870        )
2871        return this
2872
2873    @property
2874    def named_selects(self) -> t.List[str]:
2875        return self.this.unnest().named_selects
2876
2877    @property
2878    def is_star(self) -> bool:
2879        return self.this.is_star or self.expression.is_star
2880
2881    @property
2882    def selects(self) -> t.List[Expression]:
2883        return self.this.unnest().selects
2884
2885    @property
2886    def left(self) -> Expression:
2887        return self.this
2888
2889    @property
2890    def right(self) -> Expression:
2891        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:
2858    def select(
2859        self,
2860        *expressions: t.Optional[ExpOrStr],
2861        append: bool = True,
2862        dialect: DialectType = None,
2863        copy: bool = True,
2864        **opts,
2865    ) -> Union:
2866        this = maybe_copy(self, copy)
2867        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2868        this.expression.unnest().select(
2869            *expressions, append=append, dialect=dialect, copy=False, **opts
2870        )
2871        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]
2873    @property
2874    def named_selects(self) -> t.List[str]:
2875        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
2877    @property
2878    def is_star(self) -> bool:
2879        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2881    @property
2882    def selects(self) -> t.List[Expression]:
2883        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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:
3091    def sort_by(
3092        self,
3093        *expressions: t.Optional[ExpOrStr],
3094        append: bool = True,
3095        dialect: DialectType = None,
3096        copy: bool = True,
3097        **opts,
3098    ) -> Select:
3099        """
3100        Set the SORT BY expression.
3101
3102        Example:
3103            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3104            'SELECT x FROM tbl SORT BY x DESC'
3105
3106        Args:
3107            *expressions: the SQL code strings to parse.
3108                If a `Group` instance is passed, this is used as-is.
3109                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3110            append: if `True`, add to any existing expressions.
3111                Otherwise, this flattens all the `Order` expression into a single expression.
3112            dialect: the dialect used to parse the input expression.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            The modified Select expression.
3118        """
3119        return _apply_child_list_builder(
3120            *expressions,
3121            instance=self,
3122            arg="sort",
3123            append=append,
3124            copy=copy,
3125            prefix="SORT BY",
3126            into=Sort,
3127            dialect=dialect,
3128            **opts,
3129        )

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

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:
3171    def limit(
3172        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3173    ) -> Select:
3174        return _apply_builder(
3175            expression=expression,
3176            instance=self,
3177            arg="limit",
3178            into=Limit,
3179            prefix="LIMIT",
3180            dialect=dialect,
3181            copy=copy,
3182            into_arg="expression",
3183            **opts,
3184        )

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:
3186    def offset(
3187        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3188    ) -> Select:
3189        """
3190        Set the OFFSET expression.
3191
3192        Example:
3193            >>> Select().from_("tbl").select("x").offset(10).sql()
3194            'SELECT x FROM tbl OFFSET 10'
3195
3196        Args:
3197            expression: the SQL code string to parse.
3198                This can also be an integer.
3199                If a `Offset` instance is passed, this is used as-is.
3200                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3201            dialect: the dialect used to parse the input expression.
3202            copy: if `False`, modify this expression instance in-place.
3203            opts: other options to use to parse the input expressions.
3204
3205        Returns:
3206            The modified Select expression.
3207        """
3208        return _apply_builder(
3209            expression=expression,
3210            instance=self,
3211            arg="offset",
3212            into=Offset,
3213            prefix="OFFSET",
3214            dialect=dialect,
3215            copy=copy,
3216            into_arg="expression",
3217            **opts,
3218        )

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:
3220    def select(
3221        self,
3222        *expressions: t.Optional[ExpOrStr],
3223        append: bool = True,
3224        dialect: DialectType = None,
3225        copy: bool = True,
3226        **opts,
3227    ) -> Select:
3228        return _apply_list_builder(
3229            *expressions,
3230            instance=self,
3231            arg="expressions",
3232            append=append,
3233            dialect=dialect,
3234            into=Expression,
3235            copy=copy,
3236            **opts,
3237        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3610    @property
3611    def selects(self) -> t.List[Expression]:
3612        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3633    def unwrap(self) -> Subquery:
3634        expression = self
3635        while expression.same_parent and expression.is_wrapper:
3636            expression = t.cast(Subquery, expression.parent)
3637        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:
3639    def select(
3640        self,
3641        *expressions: t.Optional[ExpOrStr],
3642        append: bool = True,
3643        dialect: DialectType = None,
3644        copy: bool = True,
3645        **opts,
3646    ) -> Subquery:
3647        this = maybe_copy(self, copy)
3648        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3649        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
3651    @property
3652    def is_wrapper(self) -> bool:
3653        """
3654        Whether this Subquery acts as a simple wrapper around another expression.
3655
3656        SELECT * FROM (((SELECT * FROM t)))
3657                      ^
3658                      This corresponds to a "wrapper" Subquery node
3659        """
3660        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
3662    @property
3663    def is_star(self) -> bool:
3664        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3666    @property
3667    def output_name(self) -> str:
3668        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):
3671class TableSample(Expression):
3672    arg_types = {
3673        "this": False,
3674        "expressions": False,
3675        "method": False,
3676        "bucket_numerator": False,
3677        "bucket_denominator": False,
3678        "bucket_field": False,
3679        "percent": False,
3680        "rows": False,
3681        "size": False,
3682        "seed": False,
3683    }
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):
3686class Tag(Expression):
3687    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3688
3689    arg_types = {
3690        "this": False,
3691        "prefix": False,
3692        "postfix": False,
3693    }

Tags are used for generating arbitrary sql like SELECT x.

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

Checks whether an expression is a star.

name: str
4179    @property
4180    def name(self) -> str:
4181        return self.expression.name
output_name: str
4183    @property
4184    def output_name(self) -> str:
4185        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:
4187    @classmethod
4188    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4189        """Build a Dot object with a sequence of expressions."""
4190        if len(expressions) < 2:
4191            raise ValueError("Dot requires >= 2 expressions.")
4192
4193        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]
4195    @property
4196    def parts(self) -> t.List[Expression]:
4197        """Return the parts of a table / column in order catalog, db, table."""
4198        this, *parts = self.flatten()
4199
4200        parts.reverse()
4201
4202        for arg in ("this", "table", "db", "catalog"):
4203            part = this.args.get(arg)
4204
4205            if isinstance(part, Expression):
4206                parts.append(part)
4207
4208        parts.reverse()
4209        return parts

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

key = 'dot'
class DPipe(Binary):
4212class DPipe(Binary):
4213    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4216class EQ(Binary, Predicate):
4217    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4220class NullSafeEQ(Binary, Predicate):
4221    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4224class NullSafeNEQ(Binary, Predicate):
4225    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4229class PropertyEQ(Binary):
4230    pass
key = 'propertyeq'
class Distance(Binary):
4233class Distance(Binary):
4234    pass
key = 'distance'
class Escape(Binary):
4237class Escape(Binary):
4238    pass
key = 'escape'
class Glob(Binary, Predicate):
4241class Glob(Binary, Predicate):
4242    pass
key = 'glob'
class GT(Binary, Predicate):
4245class GT(Binary, Predicate):
4246    pass
key = 'gt'
class GTE(Binary, Predicate):
4249class GTE(Binary, Predicate):
4250    pass
key = 'gte'
class ILike(Binary, Predicate):
4253class ILike(Binary, Predicate):
4254    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4257class ILikeAny(Binary, Predicate):
4258    pass
key = 'ilikeany'
class IntDiv(Binary):
4261class IntDiv(Binary):
4262    pass
key = 'intdiv'
class Is(Binary, Predicate):
4265class Is(Binary, Predicate):
4266    pass
key = 'is'
class Kwarg(Binary):
4269class Kwarg(Binary):
4270    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4273class Like(Binary, Predicate):
4274    pass
key = 'like'
class LikeAny(Binary, Predicate):
4277class LikeAny(Binary, Predicate):
4278    pass
key = 'likeany'
class LT(Binary, Predicate):
4281class LT(Binary, Predicate):
4282    pass
key = 'lt'
class LTE(Binary, Predicate):
4285class LTE(Binary, Predicate):
4286    pass
key = 'lte'
class Mod(Binary):
4289class Mod(Binary):
4290    pass
key = 'mod'
class Mul(Binary):
4293class Mul(Binary):
4294    pass
key = 'mul'
class NEQ(Binary, Predicate):
4297class NEQ(Binary, Predicate):
4298    pass
key = 'neq'
class Operator(Binary):
4302class Operator(Binary):
4303    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4306class SimilarTo(Binary, Predicate):
4307    pass
key = 'similarto'
class Slice(Binary):
4310class Slice(Binary):
4311    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4314class Sub(Binary):
4315    pass
key = 'sub'
class Unary(Condition):
4320class Unary(Condition):
4321    pass
key = 'unary'
class BitwiseNot(Unary):
4324class BitwiseNot(Unary):
4325    pass
key = 'bitwisenot'
class Not(Unary):
4328class Not(Unary):
4329    pass
key = 'not'
class Paren(Unary):
4332class Paren(Unary):
4333    @property
4334    def output_name(self) -> str:
4335        return self.this.name
output_name: str
4333    @property
4334    def output_name(self) -> str:
4335        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):
4338class Neg(Unary):
4339    pass
key = 'neg'
class Alias(Expression):
4342class Alias(Expression):
4343    arg_types = {"this": True, "alias": False}
4344
4345    @property
4346    def output_name(self) -> str:
4347        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4345    @property
4346    def output_name(self) -> str:
4347        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):
4352class PivotAlias(Alias):
4353    pass
key = 'pivotalias'
class Aliases(Expression):
4356class Aliases(Expression):
4357    arg_types = {"this": True, "expressions": True}
4358
4359    @property
4360    def aliases(self):
4361        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4359    @property
4360    def aliases(self):
4361        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4365class AtIndex(Expression):
4366    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4369class AtTimeZone(Expression):
4370    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4373class FromTimeZone(Expression):
4374    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4377class Between(Predicate):
4378    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4381class Bracket(Condition):
4382    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4383    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4384
4385    @property
4386    def output_name(self) -> str:
4387        if len(self.expressions) == 1:
4388            return self.expressions[0].output_name
4389
4390        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4385    @property
4386    def output_name(self) -> str:
4387        if len(self.expressions) == 1:
4388            return self.expressions[0].output_name
4389
4390        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):
4393class Distinct(Expression):
4394    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4397class In(Predicate):
4398    arg_types = {
4399        "this": True,
4400        "expressions": False,
4401        "query": False,
4402        "unnest": False,
4403        "field": False,
4404        "is_global": False,
4405    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4409class ForIn(Expression):
4410    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4413class TimeUnit(Expression):
4414    """Automatically converts unit arg into a var."""
4415
4416    arg_types = {"unit": False}
4417
4418    UNABBREVIATED_UNIT_NAME = {
4419        "D": "DAY",
4420        "H": "HOUR",
4421        "M": "MINUTE",
4422        "MS": "MILLISECOND",
4423        "NS": "NANOSECOND",
4424        "Q": "QUARTER",
4425        "S": "SECOND",
4426        "US": "MICROSECOND",
4427        "W": "WEEK",
4428        "Y": "YEAR",
4429    }
4430
4431    VAR_LIKE = (Column, Literal, Var)
4432
4433    def __init__(self, **args):
4434        unit = args.get("unit")
4435        if isinstance(unit, self.VAR_LIKE):
4436            args["unit"] = Var(
4437                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4438            )
4439        elif isinstance(unit, Week):
4440            unit.set("this", Var(this=unit.this.name.upper()))
4441
4442        super().__init__(**args)
4443
4444    @property
4445    def unit(self) -> t.Optional[Var]:
4446        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4433    def __init__(self, **args):
4434        unit = args.get("unit")
4435        if isinstance(unit, self.VAR_LIKE):
4436            args["unit"] = Var(
4437                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4438            )
4439        elif isinstance(unit, Week):
4440            unit.set("this", Var(this=unit.this.name.upper()))
4441
4442        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Optional[Var]
4444    @property
4445    def unit(self) -> t.Optional[Var]:
4446        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4449class IntervalOp(TimeUnit):
4450    arg_types = {"unit": True, "expression": True}
4451
4452    def interval(self):
4453        return Interval(
4454            this=self.expression.copy(),
4455            unit=self.unit.copy(),
4456        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4452    def interval(self):
4453        return Interval(
4454            this=self.expression.copy(),
4455            unit=self.unit.copy(),
4456        )
key = 'intervalop'
class IntervalSpan(DataType):
4462class IntervalSpan(DataType):
4463    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4466class Interval(TimeUnit):
4467    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4470class IgnoreNulls(Expression):
4471    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4474class RespectNulls(Expression):
4475    pass
key = 'respectnulls'
class HavingMax(Expression):
4479class HavingMax(Expression):
4480    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4484class Func(Condition):
4485    """
4486    The base class for all function expressions.
4487
4488    Attributes:
4489        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4490            treated as a variable length argument and the argument's value will be stored as a list.
4491        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4492            function expression. These values are used to map this node to a name during parsing as
4493            well as to provide the function's name during SQL string generation. By default the SQL
4494            name is set to the expression's class name transformed to snake case.
4495    """
4496
4497    is_var_len_args = False
4498
4499    @classmethod
4500    def from_arg_list(cls, args):
4501        if cls.is_var_len_args:
4502            all_arg_keys = list(cls.arg_types)
4503            # If this function supports variable length argument treat the last argument as such.
4504            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4505            num_non_var = len(non_var_len_arg_keys)
4506
4507            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4508            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4509        else:
4510            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4511
4512        return cls(**args_dict)
4513
4514    @classmethod
4515    def sql_names(cls):
4516        if cls is Func:
4517            raise NotImplementedError(
4518                "SQL name is only supported by concrete function implementations"
4519            )
4520        if "_sql_names" not in cls.__dict__:
4521            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4522        return cls._sql_names
4523
4524    @classmethod
4525    def sql_name(cls):
4526        return cls.sql_names()[0]
4527
4528    @classmethod
4529    def default_parser_mappings(cls):
4530        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):
4499    @classmethod
4500    def from_arg_list(cls, args):
4501        if cls.is_var_len_args:
4502            all_arg_keys = list(cls.arg_types)
4503            # If this function supports variable length argument treat the last argument as such.
4504            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4505            num_non_var = len(non_var_len_arg_keys)
4506
4507            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4508            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4509        else:
4510            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4511
4512        return cls(**args_dict)
@classmethod
def sql_names(cls):
4514    @classmethod
4515    def sql_names(cls):
4516        if cls is Func:
4517            raise NotImplementedError(
4518                "SQL name is only supported by concrete function implementations"
4519            )
4520        if "_sql_names" not in cls.__dict__:
4521            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4522        return cls._sql_names
@classmethod
def sql_name(cls):
4524    @classmethod
4525    def sql_name(cls):
4526        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4528    @classmethod
4529    def default_parser_mappings(cls):
4530        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4533class AggFunc(Func):
4534    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4537class ParameterizedAgg(AggFunc):
4538    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4541class Abs(Func):
4542    pass
key = 'abs'
class ArgMax(AggFunc):
4545class ArgMax(AggFunc):
4546    arg_types = {"this": True, "expression": True, "count": False}
4547    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4550class ArgMin(AggFunc):
4551    arg_types = {"this": True, "expression": True, "count": False}
4552    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4555class ApproxTopK(AggFunc):
4556    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4559class Flatten(Func):
4560    pass
key = 'flatten'
class Transform(Func):
4564class Transform(Func):
4565    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4568class Anonymous(Func):
4569    arg_types = {"this": True, "expressions": False}
4570    is_var_len_args = True
4571
4572    @property
4573    def name(self) -> str:
4574        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
4572    @property
4573    def name(self) -> str:
4574        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4577class AnonymousAggFunc(AggFunc):
4578    arg_types = {"this": True, "expressions": False}
4579    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4583class CombinedAggFunc(AnonymousAggFunc):
4584    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4587class CombinedParameterizedAgg(ParameterizedAgg):
4588    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):
4593class Hll(AggFunc):
4594    arg_types = {"this": True, "expressions": False}
4595    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4598class ApproxDistinct(AggFunc):
4599    arg_types = {"this": True, "accuracy": False}
4600    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4603class Array(Func):
4604    arg_types = {"expressions": False}
4605    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4609class ToArray(Func):
4610    pass
key = 'toarray'
class ToChar(Func):
4615class ToChar(Func):
4616    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4621class ToNumber(Func):
4622    arg_types = {
4623        "this": True,
4624        "format": False,
4625        "nlsparam": False,
4626        "precision": False,
4627        "scale": False,
4628    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4632class Convert(Func):
4633    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4636class GenerateSeries(Func):
4637    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):
4640class ArrayAgg(AggFunc):
4641    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4644class ArrayUniqueAgg(AggFunc):
4645    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4648class ArrayAll(Func):
4649    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4653class ArrayAny(Func):
4654    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4657class ArrayConcat(Func):
4658    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4659    arg_types = {"this": True, "expressions": False}
4660    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4663class ArrayContains(Binary, Func):
4664    pass
key = 'arraycontains'
class ArrayContained(Binary):
4667class ArrayContained(Binary):
4668    pass
key = 'arraycontained'
class ArrayFilter(Func):
4671class ArrayFilter(Func):
4672    arg_types = {"this": True, "expression": True}
4673    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4676class ArrayToString(Func):
4677    arg_types = {"this": True, "expression": True, "null": False}
4678    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayOverlaps(Binary, Func):
4681class ArrayOverlaps(Binary, Func):
4682    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4685class ArraySize(Func):
4686    arg_types = {"this": True, "expression": False}
4687    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4690class ArraySort(Func):
4691    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4694class ArraySum(Func):
4695    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4698class ArrayUnionAgg(AggFunc):
4699    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4702class Avg(AggFunc):
4703    pass
key = 'avg'
class AnyValue(AggFunc):
4706class AnyValue(AggFunc):
4707    pass
key = 'anyvalue'
class Lag(AggFunc):
4710class Lag(AggFunc):
4711    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4714class Lead(AggFunc):
4715    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4720class First(AggFunc):
4721    pass
key = 'first'
class Last(AggFunc):
4724class Last(AggFunc):
4725    pass
key = 'last'
class FirstValue(AggFunc):
4728class FirstValue(AggFunc):
4729    pass
key = 'firstvalue'
class LastValue(AggFunc):
4732class LastValue(AggFunc):
4733    pass
key = 'lastvalue'
class NthValue(AggFunc):
4736class NthValue(AggFunc):
4737    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4740class Case(Func):
4741    arg_types = {"this": False, "ifs": True, "default": False}
4742
4743    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4744        instance = maybe_copy(self, copy)
4745        instance.append(
4746            "ifs",
4747            If(
4748                this=maybe_parse(condition, copy=copy, **opts),
4749                true=maybe_parse(then, copy=copy, **opts),
4750            ),
4751        )
4752        return instance
4753
4754    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4755        instance = maybe_copy(self, copy)
4756        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4757        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:
4743    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4744        instance = maybe_copy(self, copy)
4745        instance.append(
4746            "ifs",
4747            If(
4748                this=maybe_parse(condition, copy=copy, **opts),
4749                true=maybe_parse(then, copy=copy, **opts),
4750            ),
4751        )
4752        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4754    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4755        instance = maybe_copy(self, copy)
4756        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4757        return instance
key = 'case'
class Cast(Func):
4760class Cast(Func):
4761    arg_types = {
4762        "this": True,
4763        "to": True,
4764        "format": False,
4765        "safe": False,
4766        "action": False,
4767    }
4768
4769    @property
4770    def name(self) -> str:
4771        return self.this.name
4772
4773    @property
4774    def to(self) -> DataType:
4775        return self.args["to"]
4776
4777    @property
4778    def output_name(self) -> str:
4779        return self.name
4780
4781    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4782        """
4783        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4784        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4785        array<int> != array<float>.
4786
4787        Args:
4788            dtypes: the data types to compare this Cast's DataType to.
4789
4790        Returns:
4791            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4792        """
4793        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4769    @property
4770    def name(self) -> str:
4771        return self.this.name
to: DataType
4773    @property
4774    def to(self) -> DataType:
4775        return self.args["to"]
output_name: str
4777    @property
4778    def output_name(self) -> str:
4779        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:
4781    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4782        """
4783        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4784        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4785        array<int> != array<float>.
4786
4787        Args:
4788            dtypes: the data types to compare this Cast's DataType to.
4789
4790        Returns:
4791            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4792        """
4793        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):
4796class TryCast(Cast):
4797    pass
key = 'trycast'
class CastToStrType(Func):
4800class CastToStrType(Func):
4801    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4804class Collate(Binary, Func):
4805    pass
key = 'collate'
class Ceil(Func):
4808class Ceil(Func):
4809    arg_types = {"this": True, "decimals": False}
4810    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4813class Coalesce(Func):
4814    arg_types = {"this": True, "expressions": False}
4815    is_var_len_args = True
4816    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4819class Chr(Func):
4820    arg_types = {"this": True, "charset": False, "expressions": False}
4821    is_var_len_args = True
4822    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4825class Concat(Func):
4826    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4827    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4830class ConcatWs(Concat):
4831    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
4835class ConnectByRoot(Func):
4836    pass
key = 'connectbyroot'
class Count(AggFunc):
4839class Count(AggFunc):
4840    arg_types = {"this": False, "expressions": False}
4841    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4844class CountIf(AggFunc):
4845    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
4849class Cbrt(Func):
4850    pass
key = 'cbrt'
class CurrentDate(Func):
4853class CurrentDate(Func):
4854    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4857class CurrentDatetime(Func):
4858    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4861class CurrentTime(Func):
4862    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4865class CurrentTimestamp(Func):
4866    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4869class CurrentUser(Func):
4870    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4873class DateAdd(Func, IntervalOp):
4874    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4877class DateSub(Func, IntervalOp):
4878    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4881class DateDiff(Func, TimeUnit):
4882    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4883    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4886class DateTrunc(Func):
4887    arg_types = {"unit": True, "this": True, "zone": False}
4888
4889    def __init__(self, **args):
4890        unit = args.get("unit")
4891        if isinstance(unit, TimeUnit.VAR_LIKE):
4892            args["unit"] = Literal.string(
4893                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4894            )
4895        elif isinstance(unit, Week):
4896            unit.set("this", Literal.string(unit.this.name.upper()))
4897
4898        super().__init__(**args)
4899
4900    @property
4901    def unit(self) -> Expression:
4902        return self.args["unit"]
DateTrunc(**args)
4889    def __init__(self, **args):
4890        unit = args.get("unit")
4891        if isinstance(unit, TimeUnit.VAR_LIKE):
4892            args["unit"] = Literal.string(
4893                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4894            )
4895        elif isinstance(unit, Week):
4896            unit.set("this", Literal.string(unit.this.name.upper()))
4897
4898        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4900    @property
4901    def unit(self) -> Expression:
4902        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4905class DatetimeAdd(Func, IntervalOp):
4906    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4909class DatetimeSub(Func, IntervalOp):
4910    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4913class DatetimeDiff(Func, TimeUnit):
4914    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4917class DatetimeTrunc(Func, TimeUnit):
4918    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4921class DayOfWeek(Func):
4922    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4925class DayOfMonth(Func):
4926    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4929class DayOfYear(Func):
4930    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4933class ToDays(Func):
4934    pass
key = 'todays'
class WeekOfYear(Func):
4937class WeekOfYear(Func):
4938    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4941class MonthsBetween(Func):
4942    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4945class LastDay(Func, TimeUnit):
4946    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4947    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4950class Extract(Func):
4951    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4954class Timestamp(Func):
4955    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4958class TimestampAdd(Func, TimeUnit):
4959    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4962class TimestampSub(Func, TimeUnit):
4963    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4966class TimestampDiff(Func, TimeUnit):
4967    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
4968    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4971class TimestampTrunc(Func, TimeUnit):
4972    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4975class TimeAdd(Func, TimeUnit):
4976    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4979class TimeSub(Func, TimeUnit):
4980    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4983class TimeDiff(Func, TimeUnit):
4984    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4987class TimeTrunc(Func, TimeUnit):
4988    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4991class DateFromParts(Func):
4992    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4993    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4996class TimeFromParts(Func):
4997    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4998    arg_types = {
4999        "hour": True,
5000        "min": True,
5001        "sec": True,
5002        "nano": False,
5003        "fractions": False,
5004        "precision": False,
5005    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5008class DateStrToDate(Func):
5009    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5012class DateToDateStr(Func):
5013    pass
key = 'datetodatestr'
class DateToDi(Func):
5016class DateToDi(Func):
5017    pass
key = 'datetodi'
class Date(Func):
5021class Date(Func):
5022    arg_types = {"this": False, "zone": False, "expressions": False}
5023    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5026class Day(Func):
5027    pass
key = 'day'
class Decode(Func):
5030class Decode(Func):
5031    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5034class DiToDate(Func):
5035    pass
key = 'ditodate'
class Encode(Func):
5038class Encode(Func):
5039    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5042class Exp(Func):
5043    pass
key = 'exp'
class Explode(Func):
5047class Explode(Func):
5048    arg_types = {"this": True, "expressions": False}
5049    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5052class ExplodeOuter(Explode):
5053    pass
key = 'explodeouter'
class Posexplode(Explode):
5056class Posexplode(Explode):
5057    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5060class PosexplodeOuter(Posexplode, ExplodeOuter):
5061    pass
key = 'posexplodeouter'
class Floor(Func):
5064class Floor(Func):
5065    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5068class FromBase64(Func):
5069    pass
key = 'frombase64'
class ToBase64(Func):
5072class ToBase64(Func):
5073    pass
key = 'tobase64'
class GenerateDateArray(Func):
5076class GenerateDateArray(Func):
5077    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5080class Greatest(Func):
5081    arg_types = {"this": True, "expressions": False}
5082    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5085class GroupConcat(AggFunc):
5086    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5089class Hex(Func):
5090    pass
key = 'hex'
class Xor(Connector, Func):
5093class Xor(Connector, Func):
5094    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5097class If(Func):
5098    arg_types = {"this": True, "true": True, "false": False}
5099    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5102class Nullif(Func):
5103    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5106class Initcap(Func):
5107    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5110class IsNan(Func):
5111    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5114class IsInf(Func):
5115    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5118class JSONPath(Expression):
5119    arg_types = {"expressions": True}
5120
5121    @property
5122    def output_name(self) -> str:
5123        last_segment = self.expressions[-1].this
5124        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5121    @property
5122    def output_name(self) -> str:
5123        last_segment = self.expressions[-1].this
5124        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):
5127class JSONPathPart(Expression):
5128    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5131class JSONPathFilter(JSONPathPart):
5132    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5135class JSONPathKey(JSONPathPart):
5136    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5139class JSONPathRecursive(JSONPathPart):
5140    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5143class JSONPathRoot(JSONPathPart):
5144    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5147class JSONPathScript(JSONPathPart):
5148    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5151class JSONPathSlice(JSONPathPart):
5152    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5155class JSONPathSelector(JSONPathPart):
5156    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5159class JSONPathSubscript(JSONPathPart):
5160    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5163class JSONPathUnion(JSONPathPart):
5164    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5167class JSONPathWildcard(JSONPathPart):
5168    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5171class FormatJson(Expression):
5172    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5175class JSONKeyValue(Expression):
5176    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5179class JSONObject(Func):
5180    arg_types = {
5181        "expressions": False,
5182        "null_handling": False,
5183        "unique_keys": False,
5184        "return_type": False,
5185        "encoding": False,
5186    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5189class JSONObjectAgg(AggFunc):
5190    arg_types = {
5191        "expressions": False,
5192        "null_handling": False,
5193        "unique_keys": False,
5194        "return_type": False,
5195        "encoding": False,
5196    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5200class JSONArray(Func):
5201    arg_types = {
5202        "expressions": True,
5203        "null_handling": False,
5204        "return_type": False,
5205        "strict": False,
5206    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5210class JSONArrayAgg(Func):
5211    arg_types = {
5212        "this": True,
5213        "order": False,
5214        "null_handling": False,
5215        "return_type": False,
5216        "strict": False,
5217    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5222class JSONColumnDef(Expression):
5223    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):
5226class JSONSchema(Expression):
5227    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5231class JSONTable(Func):
5232    arg_types = {
5233        "this": True,
5234        "schema": True,
5235        "path": False,
5236        "error_handling": False,
5237        "empty_handling": False,
5238    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5241class OpenJSONColumnDef(Expression):
5242    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):
5245class OpenJSON(Func):
5246    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5249class JSONBContains(Binary):
5250    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5253class JSONExtract(Binary, Func):
5254    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5255    _sql_names = ["JSON_EXTRACT"]
5256    is_var_len_args = True
5257
5258    @property
5259    def output_name(self) -> str:
5260        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
5258    @property
5259    def output_name(self) -> str:
5260        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):
5263class JSONExtractScalar(Binary, Func):
5264    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5265    _sql_names = ["JSON_EXTRACT_SCALAR"]
5266    is_var_len_args = True
5267
5268    @property
5269    def output_name(self) -> str:
5270        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
5268    @property
5269    def output_name(self) -> str:
5270        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):
5273class JSONBExtract(Binary, Func):
5274    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5277class JSONBExtractScalar(Binary, Func):
5278    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5281class JSONFormat(Func):
5282    arg_types = {"this": False, "options": False}
5283    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5287class JSONArrayContains(Binary, Predicate, Func):
5288    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5291class ParseJSON(Func):
5292    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5293    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5294    arg_types = {"this": True, "expressions": False}
5295    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5298class Least(Func):
5299    arg_types = {"this": True, "expressions": False}
5300    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5303class Left(Func):
5304    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5311class Length(Func):
5312    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5315class Levenshtein(Func):
5316    arg_types = {
5317        "this": True,
5318        "expression": False,
5319        "ins_cost": False,
5320        "del_cost": False,
5321        "sub_cost": False,
5322    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5325class Ln(Func):
5326    pass
key = 'ln'
class Log(Func):
5329class Log(Func):
5330    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5333class LogicalOr(AggFunc):
5334    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5337class LogicalAnd(AggFunc):
5338    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5341class Lower(Func):
5342    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5345class Map(Func):
5346    arg_types = {"keys": False, "values": False}
5347
5348    @property
5349    def keys(self) -> t.List[Expression]:
5350        keys = self.args.get("keys")
5351        return keys.expressions if keys else []
5352
5353    @property
5354    def values(self) -> t.List[Expression]:
5355        values = self.args.get("values")
5356        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5348    @property
5349    def keys(self) -> t.List[Expression]:
5350        keys = self.args.get("keys")
5351        return keys.expressions if keys else []
values: List[Expression]
5353    @property
5354    def values(self) -> t.List[Expression]:
5355        values = self.args.get("values")
5356        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5359class MapFromEntries(Func):
5360    pass
key = 'mapfromentries'
class StarMap(Func):
5363class StarMap(Func):
5364    pass
key = 'starmap'
class VarMap(Func):
5367class VarMap(Func):
5368    arg_types = {"keys": True, "values": True}
5369    is_var_len_args = True
5370
5371    @property
5372    def keys(self) -> t.List[Expression]:
5373        return self.args["keys"].expressions
5374
5375    @property
5376    def values(self) -> t.List[Expression]:
5377        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5371    @property
5372    def keys(self) -> t.List[Expression]:
5373        return self.args["keys"].expressions
values: List[Expression]
5375    @property
5376    def values(self) -> t.List[Expression]:
5377        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5381class MatchAgainst(Func):
5382    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5385class Max(AggFunc):
5386    arg_types = {"this": True, "expressions": False}
5387    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5390class MD5(Func):
5391    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5395class MD5Digest(Func):
5396    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5399class Min(AggFunc):
5400    arg_types = {"this": True, "expressions": False}
5401    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5404class Month(Func):
5405    pass
key = 'month'
class AddMonths(Func):
5408class AddMonths(Func):
5409    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5412class Nvl2(Func):
5413    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5417class Predict(Func):
5418    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5421class Pow(Binary, Func):
5422    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5425class PercentileCont(AggFunc):
5426    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5429class PercentileDisc(AggFunc):
5430    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5433class Quantile(AggFunc):
5434    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5437class ApproxQuantile(Quantile):
5438    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):
5441class Rand(Func):
5442    _sql_names = ["RAND", "RANDOM"]
5443    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5446class Randn(Func):
5447    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5450class RangeN(Func):
5451    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5454class ReadCSV(Func):
5455    _sql_names = ["READ_CSV"]
5456    is_var_len_args = True
5457    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5460class Reduce(Func):
5461    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):
5464class RegexpExtract(Func):
5465    arg_types = {
5466        "this": True,
5467        "expression": True,
5468        "position": False,
5469        "occurrence": False,
5470        "parameters": False,
5471        "group": False,
5472    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5475class RegexpReplace(Func):
5476    arg_types = {
5477        "this": True,
5478        "expression": True,
5479        "replacement": False,
5480        "position": False,
5481        "occurrence": False,
5482        "parameters": False,
5483        "modifiers": False,
5484    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5487class RegexpLike(Binary, Func):
5488    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5491class RegexpILike(Binary, Func):
5492    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5497class RegexpSplit(Func):
5498    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5501class Repeat(Func):
5502    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5507class Round(Func):
5508    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5511class RowNumber(Func):
5512    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5515class SafeDivide(Func):
5516    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5519class SHA(Func):
5520    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5523class SHA2(Func):
5524    _sql_names = ["SHA2"]
5525    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5528class Sign(Func):
5529    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5532class SortArray(Func):
5533    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5536class Split(Func):
5537    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5542class Substring(Func):
5543    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5546class StandardHash(Func):
5547    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5550class StartsWith(Func):
5551    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5552    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5555class StrPosition(Func):
5556    arg_types = {
5557        "this": True,
5558        "substr": True,
5559        "position": False,
5560        "instance": False,
5561    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5564class StrToDate(Func):
5565    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5568class StrToTime(Func):
5569    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5574class StrToUnix(Func):
5575    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5580class StrToMap(Func):
5581    arg_types = {
5582        "this": True,
5583        "pair_delim": False,
5584        "key_value_delim": False,
5585        "duplicate_resolution_callback": False,
5586    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5589class NumberToStr(Func):
5590    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5593class FromBase(Func):
5594    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5597class Struct(Func):
5598    arg_types = {"expressions": False}
5599    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5602class StructExtract(Func):
5603    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5608class Stuff(Func):
5609    _sql_names = ["STUFF", "INSERT"]
5610    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):
5613class Sum(AggFunc):
5614    pass
key = 'sum'
class Sqrt(Func):
5617class Sqrt(Func):
5618    pass
key = 'sqrt'
class Stddev(AggFunc):
5621class Stddev(AggFunc):
5622    pass
key = 'stddev'
class StddevPop(AggFunc):
5625class StddevPop(AggFunc):
5626    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5629class StddevSamp(AggFunc):
5630    pass
key = 'stddevsamp'
class TimeToStr(Func):
5633class TimeToStr(Func):
5634    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5637class TimeToTimeStr(Func):
5638    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5641class TimeToUnix(Func):
5642    pass
key = 'timetounix'
class TimeStrToDate(Func):
5645class TimeStrToDate(Func):
5646    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5649class TimeStrToTime(Func):
5650    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5653class TimeStrToUnix(Func):
5654    pass
key = 'timestrtounix'
class Trim(Func):
5657class Trim(Func):
5658    arg_types = {
5659        "this": True,
5660        "expression": False,
5661        "position": False,
5662        "collation": False,
5663    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5666class TsOrDsAdd(Func, TimeUnit):
5667    # return_type is used to correctly cast the arguments of this expression when transpiling it
5668    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5669
5670    @property
5671    def return_type(self) -> DataType:
5672        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
5670    @property
5671    def return_type(self) -> DataType:
5672        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5675class TsOrDsDiff(Func, TimeUnit):
5676    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5679class TsOrDsToDateStr(Func):
5680    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5683class TsOrDsToDate(Func):
5684    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5687class TsOrDsToTime(Func):
5688    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5691class TsOrDiToDi(Func):
5692    pass
key = 'tsorditodi'
class Unhex(Func):
5695class Unhex(Func):
5696    pass
key = 'unhex'
class UnixDate(Func):
5700class UnixDate(Func):
5701    pass
key = 'unixdate'
class UnixToStr(Func):
5704class UnixToStr(Func):
5705    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5710class UnixToTime(Func):
5711    arg_types = {
5712        "this": True,
5713        "scale": False,
5714        "zone": False,
5715        "hours": False,
5716        "minutes": False,
5717        "format": False,
5718    }
5719
5720    SECONDS = Literal.number(0)
5721    DECIS = Literal.number(1)
5722    CENTIS = Literal.number(2)
5723    MILLIS = Literal.number(3)
5724    DECIMILLIS = Literal.number(4)
5725    CENTIMILLIS = Literal.number(5)
5726    MICROS = Literal.number(6)
5727    DECIMICROS = Literal.number(7)
5728    CENTIMICROS = Literal.number(8)
5729    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):
5732class UnixToTimeStr(Func):
5733    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5736class TimestampFromParts(Func):
5737    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5738    arg_types = {
5739        "year": True,
5740        "month": True,
5741        "day": True,
5742        "hour": True,
5743        "min": True,
5744        "sec": True,
5745        "nano": False,
5746        "zone": False,
5747        "milli": False,
5748    }
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):
5751class Upper(Func):
5752    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5755class Corr(Binary, AggFunc):
5756    pass
key = 'corr'
class Variance(AggFunc):
5759class Variance(AggFunc):
5760    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5763class VariancePop(AggFunc):
5764    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5767class CovarSamp(Binary, AggFunc):
5768    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5771class CovarPop(Binary, AggFunc):
5772    pass
key = 'covarpop'
class Week(Func):
5775class Week(Func):
5776    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5779class XMLTable(Func):
5780    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):
5783class Year(Func):
5784    pass
key = 'year'
class Use(Expression):
5787class Use(Expression):
5788    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5791class Merge(Expression):
5792    arg_types = {
5793        "this": True,
5794        "using": True,
5795        "on": True,
5796        "expressions": True,
5797        "with": False,
5798    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5801class When(Func):
5802    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):
5807class NextValueFor(Func):
5808    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 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, '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_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5846def maybe_parse(
5847    sql_or_expression: ExpOrStr,
5848    *,
5849    into: t.Optional[IntoType] = None,
5850    dialect: DialectType = None,
5851    prefix: t.Optional[str] = None,
5852    copy: bool = False,
5853    **opts,
5854) -> Expression:
5855    """Gracefully handle a possible string or expression.
5856
5857    Example:
5858        >>> maybe_parse("1")
5859        Literal(this=1, is_string=False)
5860        >>> maybe_parse(to_identifier("x"))
5861        Identifier(this=x, quoted=False)
5862
5863    Args:
5864        sql_or_expression: the SQL code string or an expression
5865        into: the SQLGlot Expression to parse into
5866        dialect: the dialect used to parse the input expressions (in the case that an
5867            input expression is a SQL string).
5868        prefix: a string to prefix the sql with before it gets parsed
5869            (automatically includes a space)
5870        copy: whether to copy the expression.
5871        **opts: other options to use to parse the input expressions (again, in the case
5872            that an input expression is a SQL string).
5873
5874    Returns:
5875        Expression: the parsed or given expression.
5876    """
5877    if isinstance(sql_or_expression, Expression):
5878        if copy:
5879            return sql_or_expression.copy()
5880        return sql_or_expression
5881
5882    if sql_or_expression is None:
5883        raise ParseError("SQL cannot be None")
5884
5885    import sqlglot
5886
5887    sql = str(sql_or_expression)
5888    if prefix:
5889        sql = f"{prefix} {sql}"
5890
5891    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):
5902def maybe_copy(instance, copy=True):
5903    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:
6117def union(
6118    left: ExpOrStr,
6119    right: ExpOrStr,
6120    distinct: bool = True,
6121    dialect: DialectType = None,
6122    copy: bool = True,
6123    **opts,
6124) -> Union:
6125    """
6126    Initializes a syntax tree from one UNION expression.
6127
6128    Example:
6129        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6130        'SELECT * FROM foo UNION SELECT * FROM bla'
6131
6132    Args:
6133        left: the SQL code string corresponding to the left-hand side.
6134            If an `Expression` instance is passed, it will be used as-is.
6135        right: the SQL code string corresponding to the right-hand side.
6136            If an `Expression` instance is passed, it will be used as-is.
6137        distinct: set the DISTINCT flag if and only if this is true.
6138        dialect: the dialect used to parse the input expression.
6139        copy: whether to copy the expression.
6140        opts: other options to use to parse the input expressions.
6141
6142    Returns:
6143        The new Union instance.
6144    """
6145    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6146    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6147
6148    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:
6151def intersect(
6152    left: ExpOrStr,
6153    right: ExpOrStr,
6154    distinct: bool = True,
6155    dialect: DialectType = None,
6156    copy: bool = True,
6157    **opts,
6158) -> Intersect:
6159    """
6160    Initializes a syntax tree from one INTERSECT expression.
6161
6162    Example:
6163        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6164        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6165
6166    Args:
6167        left: the SQL code string corresponding to the left-hand side.
6168            If an `Expression` instance is passed, it will be used as-is.
6169        right: the SQL code string corresponding to the right-hand side.
6170            If an `Expression` instance is passed, it will be used as-is.
6171        distinct: set the DISTINCT flag if and only if this is true.
6172        dialect: the dialect used to parse the input expression.
6173        copy: whether to copy the expression.
6174        opts: other options to use to parse the input expressions.
6175
6176    Returns:
6177        The new Intersect instance.
6178    """
6179    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6180    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6181
6182    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:
6185def except_(
6186    left: ExpOrStr,
6187    right: ExpOrStr,
6188    distinct: bool = True,
6189    dialect: DialectType = None,
6190    copy: bool = True,
6191    **opts,
6192) -> Except:
6193    """
6194    Initializes a syntax tree from one EXCEPT expression.
6195
6196    Example:
6197        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6198        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6199
6200    Args:
6201        left: the SQL code string corresponding to the left-hand side.
6202            If an `Expression` instance is passed, it will be used as-is.
6203        right: the SQL code string corresponding to the right-hand side.
6204            If an `Expression` instance is passed, it will be used as-is.
6205        distinct: set the DISTINCT flag if and only if this is true.
6206        dialect: the dialect used to parse the input expression.
6207        copy: whether to copy the expression.
6208        opts: other options to use to parse the input expressions.
6209
6210    Returns:
6211        The new Except instance.
6212    """
6213    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6214    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6215
6216    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:
6219def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6220    """
6221    Initializes a syntax tree from one or multiple SELECT expressions.
6222
6223    Example:
6224        >>> select("col1", "col2").from_("tbl").sql()
6225        'SELECT col1, col2 FROM tbl'
6226
6227    Args:
6228        *expressions: the SQL code string to parse as the expressions of a
6229            SELECT statement. If an Expression instance is passed, this is used as-is.
6230        dialect: the dialect used to parse the input expressions (in the case that an
6231            input expression is a SQL string).
6232        **opts: other options to use to parse the input expressions (again, in the case
6233            that an input expression is a SQL string).
6234
6235    Returns:
6236        Select: the syntax tree for the SELECT statement.
6237    """
6238    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:
6241def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6242    """
6243    Initializes a syntax tree from a FROM expression.
6244
6245    Example:
6246        >>> from_("tbl").select("col1", "col2").sql()
6247        'SELECT col1, col2 FROM tbl'
6248
6249    Args:
6250        *expression: the SQL code string to parse as the FROM expressions of a
6251            SELECT statement. If an Expression instance is passed, this is used as-is.
6252        dialect: the dialect used to parse the input expression (in the case that the
6253            input expression is a SQL string).
6254        **opts: other options to use to parse the input expressions (again, in the case
6255            that the input expression is a SQL string).
6256
6257    Returns:
6258        Select: the syntax tree for the SELECT statement.
6259    """
6260    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:
6263def update(
6264    table: str | Table,
6265    properties: dict,
6266    where: t.Optional[ExpOrStr] = None,
6267    from_: t.Optional[ExpOrStr] = None,
6268    dialect: DialectType = None,
6269    **opts,
6270) -> Update:
6271    """
6272    Creates an update statement.
6273
6274    Example:
6275        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6276        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6277
6278    Args:
6279        *properties: dictionary of properties to set which are
6280            auto converted to sql objects eg None -> NULL
6281        where: sql conditional parsed into a WHERE statement
6282        from_: sql statement parsed into a FROM statement
6283        dialect: the dialect used to parse the input expressions.
6284        **opts: other options to use to parse the input expressions.
6285
6286    Returns:
6287        Update: the syntax tree for the UPDATE statement.
6288    """
6289    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6290    update_expr.set(
6291        "expressions",
6292        [
6293            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6294            for k, v in properties.items()
6295        ],
6296    )
6297    if from_:
6298        update_expr.set(
6299            "from",
6300            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6301        )
6302    if isinstance(where, Condition):
6303        where = Where(this=where)
6304    if where:
6305        update_expr.set(
6306            "where",
6307            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6308        )
6309    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:
6312def delete(
6313    table: ExpOrStr,
6314    where: t.Optional[ExpOrStr] = None,
6315    returning: t.Optional[ExpOrStr] = None,
6316    dialect: DialectType = None,
6317    **opts,
6318) -> Delete:
6319    """
6320    Builds a delete statement.
6321
6322    Example:
6323        >>> delete("my_table", where="id > 1").sql()
6324        'DELETE FROM my_table WHERE id > 1'
6325
6326    Args:
6327        where: sql conditional parsed into a WHERE statement
6328        returning: sql conditional parsed into a RETURNING statement
6329        dialect: the dialect used to parse the input expressions.
6330        **opts: other options to use to parse the input expressions.
6331
6332    Returns:
6333        Delete: the syntax tree for the DELETE statement.
6334    """
6335    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6336    if where:
6337        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6338    if returning:
6339        delete_expr = t.cast(
6340            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6341        )
6342    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:
6345def insert(
6346    expression: ExpOrStr,
6347    into: ExpOrStr,
6348    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6349    overwrite: t.Optional[bool] = None,
6350    returning: t.Optional[ExpOrStr] = None,
6351    dialect: DialectType = None,
6352    copy: bool = True,
6353    **opts,
6354) -> Insert:
6355    """
6356    Builds an INSERT statement.
6357
6358    Example:
6359        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6360        'INSERT INTO tbl VALUES (1, 2, 3)'
6361
6362    Args:
6363        expression: the sql string or expression of the INSERT statement
6364        into: the tbl to insert data to.
6365        columns: optionally the table's column names.
6366        overwrite: whether to INSERT OVERWRITE or not.
6367        returning: sql conditional parsed into a RETURNING statement
6368        dialect: the dialect used to parse the input expressions.
6369        copy: whether to copy the expression.
6370        **opts: other options to use to parse the input expressions.
6371
6372    Returns:
6373        Insert: the syntax tree for the INSERT statement.
6374    """
6375    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6376    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6377
6378    if columns:
6379        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6380
6381    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6382
6383    if returning:
6384        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6385
6386    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:
6389def condition(
6390    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6391) -> Condition:
6392    """
6393    Initialize a logical condition expression.
6394
6395    Example:
6396        >>> condition("x=1").sql()
6397        'x = 1'
6398
6399        This is helpful for composing larger logical syntax trees:
6400        >>> where = condition("x=1")
6401        >>> where = where.and_("y=1")
6402        >>> Select().from_("tbl").select("*").where(where).sql()
6403        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6404
6405    Args:
6406        *expression: the SQL code string to parse.
6407            If an Expression instance is passed, this is used as-is.
6408        dialect: the dialect used to parse the input expression (in the case that the
6409            input expression is a SQL string).
6410        copy: Whether to copy `expression` (only applies to expressions).
6411        **opts: other options to use to parse the input expressions (again, in the case
6412            that the input expression is a SQL string).
6413
6414    Returns:
6415        The new Condition instance
6416    """
6417    return maybe_parse(
6418        expression,
6419        into=Condition,
6420        dialect=dialect,
6421        copy=copy,
6422        **opts,
6423    )

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:
6426def and_(
6427    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6428) -> Condition:
6429    """
6430    Combine multiple conditions with an AND logical operator.
6431
6432    Example:
6433        >>> and_("x=1", and_("y=1", "z=1")).sql()
6434        'x = 1 AND (y = 1 AND z = 1)'
6435
6436    Args:
6437        *expressions: the SQL code strings to parse.
6438            If an Expression instance is passed, this is used as-is.
6439        dialect: the dialect used to parse the input expression.
6440        copy: whether to copy `expressions` (only applies to Expressions).
6441        **opts: other options to use to parse the input expressions.
6442
6443    Returns:
6444        And: the new condition
6445    """
6446    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:
6449def or_(
6450    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6451) -> Condition:
6452    """
6453    Combine multiple conditions with an OR logical operator.
6454
6455    Example:
6456        >>> or_("x=1", or_("y=1", "z=1")).sql()
6457        'x = 1 OR (y = 1 OR z = 1)'
6458
6459    Args:
6460        *expressions: the SQL code strings to parse.
6461            If an Expression instance is passed, this is used as-is.
6462        dialect: the dialect used to parse the input expression.
6463        copy: whether to copy `expressions` (only applies to Expressions).
6464        **opts: other options to use to parse the input expressions.
6465
6466    Returns:
6467        Or: the new condition
6468    """
6469    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:
6472def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6473    """
6474    Wrap a condition with a NOT operator.
6475
6476    Example:
6477        >>> not_("this_suit='black'").sql()
6478        "NOT this_suit = 'black'"
6479
6480    Args:
6481        expression: the SQL code string to parse.
6482            If an Expression instance is passed, this is used as-is.
6483        dialect: the dialect used to parse the input expression.
6484        copy: whether to copy the expression or not.
6485        **opts: other options to use to parse the input expressions.
6486
6487    Returns:
6488        The new condition.
6489    """
6490    this = condition(
6491        expression,
6492        dialect=dialect,
6493        copy=copy,
6494        **opts,
6495    )
6496    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:
6499def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6500    """
6501    Wrap an expression in parentheses.
6502
6503    Example:
6504        >>> paren("5 + 3").sql()
6505        '(5 + 3)'
6506
6507    Args:
6508        expression: the SQL code string to parse.
6509            If an Expression instance is passed, this is used as-is.
6510        copy: whether to copy the expression or not.
6511
6512    Returns:
6513        The wrapped expression.
6514    """
6515    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):
6531def to_identifier(name, quoted=None, copy=True):
6532    """Builds an identifier.
6533
6534    Args:
6535        name: The name to turn into an identifier.
6536        quoted: Whether to force quote the identifier.
6537        copy: Whether to copy name if it's an Identifier.
6538
6539    Returns:
6540        The identifier ast node.
6541    """
6542
6543    if name is None:
6544        return None
6545
6546    if isinstance(name, Identifier):
6547        identifier = maybe_copy(name, copy)
6548    elif isinstance(name, str):
6549        identifier = Identifier(
6550            this=name,
6551            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6552        )
6553    else:
6554        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6555    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:
6558def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6559    """
6560    Parses a given string into an identifier.
6561
6562    Args:
6563        name: The name to parse into an identifier.
6564        dialect: The dialect to parse against.
6565
6566    Returns:
6567        The identifier ast node.
6568    """
6569    try:
6570        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6571    except ParseError:
6572        expression = to_identifier(name)
6573
6574    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:
6580def to_interval(interval: str | Literal) -> Interval:
6581    """Builds an interval expression from a string like '1 day' or '5 months'."""
6582    if isinstance(interval, Literal):
6583        if not interval.is_string:
6584            raise ValueError("Invalid interval string.")
6585
6586        interval = interval.this
6587
6588    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6589
6590    if not interval_parts:
6591        raise ValueError("Invalid interval string.")
6592
6593    return Interval(
6594        this=Literal.string(interval_parts.group(1)),
6595        unit=Var(this=interval_parts.group(2).upper()),
6596    )

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

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6607def to_table(
6608    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6609) -> t.Optional[Table]:
6610    """
6611    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6612    If a table is passed in then that table is returned.
6613
6614    Args:
6615        sql_path: a `[catalog].[schema].[table]` string.
6616        dialect: the source dialect according to which the table name will be parsed.
6617        copy: Whether to copy a table if it is passed in.
6618        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6619
6620    Returns:
6621        A table expression.
6622    """
6623    if sql_path is None or isinstance(sql_path, Table):
6624        return maybe_copy(sql_path, copy=copy)
6625    if not isinstance(sql_path, str):
6626        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6627
6628    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6629    if table:
6630        for k, v in kwargs.items():
6631            table.set(k, v)
6632
6633    return table

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

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

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6636def to_column(sql_path: str | Column, **kwargs) -> Column:
6637    """
6638    Create a column from a `[table].[column]` sql path. Schema is optional.
6639
6640    If a column is passed in then that column is returned.
6641
6642    Args:
6643        sql_path: `[table].[column]` string
6644    Returns:
6645        Table: A column expression
6646    """
6647    if sql_path is None or isinstance(sql_path, Column):
6648        return sql_path
6649    if not isinstance(sql_path, str):
6650        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6651    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: A column expression

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
6654def alias_(
6655    expression: ExpOrStr,
6656    alias: t.Optional[str | Identifier],
6657    table: bool | t.Sequence[str | Identifier] = False,
6658    quoted: t.Optional[bool] = None,
6659    dialect: DialectType = None,
6660    copy: bool = True,
6661    **opts,
6662):
6663    """Create an Alias expression.
6664
6665    Example:
6666        >>> alias_('foo', 'bar').sql()
6667        'foo AS bar'
6668
6669        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6670        '(SELECT 1, 2) AS bar(a, b)'
6671
6672    Args:
6673        expression: the SQL code strings to parse.
6674            If an Expression instance is passed, this is used as-is.
6675        alias: the alias name to use. If the name has
6676            special characters it is quoted.
6677        table: Whether to create a table alias, can also be a list of columns.
6678        quoted: whether to quote the alias
6679        dialect: the dialect used to parse the input expression.
6680        copy: Whether to copy the expression.
6681        **opts: other options to use to parse the input expressions.
6682
6683    Returns:
6684        Alias: the aliased expression
6685    """
6686    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6687    alias = to_identifier(alias, quoted=quoted)
6688
6689    if table:
6690        table_alias = TableAlias(this=alias)
6691        exp.set("alias", table_alias)
6692
6693        if not isinstance(table, bool):
6694            for column in table:
6695                table_alias.append("columns", to_identifier(column, quoted=quoted))
6696
6697        return exp
6698
6699    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6700    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6701    # for the complete Window expression.
6702    #
6703    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6704
6705    if "alias" in exp.arg_types and not isinstance(exp, Window):
6706        exp.set("alias", alias)
6707        return exp
6708    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:
6711def subquery(
6712    expression: ExpOrStr,
6713    alias: t.Optional[Identifier | str] = None,
6714    dialect: DialectType = None,
6715    **opts,
6716) -> Select:
6717    """
6718    Build a subquery expression that's selected from.
6719
6720    Example:
6721        >>> subquery('select x from tbl', 'bar').select('x').sql()
6722        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6723
6724    Args:
6725        expression: the SQL code strings to parse.
6726            If an Expression instance is passed, this is used as-is.
6727        alias: the alias name to use.
6728        dialect: the dialect used to parse the input expression.
6729        **opts: other options to use to parse the input expressions.
6730
6731    Returns:
6732        A new Select instance with the subquery expression included.
6733    """
6734
6735    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6736    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):
6767def column(
6768    col,
6769    table=None,
6770    db=None,
6771    catalog=None,
6772    *,
6773    fields=None,
6774    quoted=None,
6775    copy=True,
6776):
6777    """
6778    Build a Column.
6779
6780    Args:
6781        col: Column name.
6782        table: Table name.
6783        db: Database name.
6784        catalog: Catalog name.
6785        fields: Additional fields using dots.
6786        quoted: Whether to force quotes on the column's identifiers.
6787        copy: Whether to copy identifiers if passed in.
6788
6789    Returns:
6790        The new Column instance.
6791    """
6792    this = Column(
6793        this=to_identifier(col, quoted=quoted, copy=copy),
6794        table=to_identifier(table, quoted=quoted, copy=copy),
6795        db=to_identifier(db, quoted=quoted, copy=copy),
6796        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6797    )
6798
6799    if fields:
6800        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6801    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:
6804def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
6805    """Cast an expression to a data type.
6806
6807    Example:
6808        >>> cast('x + 1', 'int').sql()
6809        'CAST(x + 1 AS INT)'
6810
6811    Args:
6812        expression: The expression to cast.
6813        to: The datatype to cast to.
6814        copy: Whether to copy the supplied expressions.
6815
6816    Returns:
6817        The new Cast instance.
6818    """
6819    expression = maybe_parse(expression, copy=copy, **opts)
6820    data_type = DataType.build(to, copy=copy, **opts)
6821    expression = Cast(this=expression, to=data_type)
6822    expression.type = data_type
6823    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:
6826def table_(
6827    table: Identifier | str,
6828    db: t.Optional[Identifier | str] = None,
6829    catalog: t.Optional[Identifier | str] = None,
6830    quoted: t.Optional[bool] = None,
6831    alias: t.Optional[Identifier | str] = None,
6832) -> Table:
6833    """Build a Table.
6834
6835    Args:
6836        table: Table name.
6837        db: Database name.
6838        catalog: Catalog name.
6839        quote: Whether to force quotes on the table's identifiers.
6840        alias: Table's alias.
6841
6842    Returns:
6843        The new Table instance.
6844    """
6845    return Table(
6846        this=to_identifier(table, quoted=quoted) if table else None,
6847        db=to_identifier(db, quoted=quoted) if db else None,
6848        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6849        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6850    )

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:
6853def values(
6854    values: t.Iterable[t.Tuple[t.Any, ...]],
6855    alias: t.Optional[str] = None,
6856    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6857) -> Values:
6858    """Build VALUES statement.
6859
6860    Example:
6861        >>> values([(1, '2')]).sql()
6862        "VALUES (1, '2')"
6863
6864    Args:
6865        values: values statements that will be converted to SQL
6866        alias: optional alias
6867        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6868         If either are provided then an alias is also required.
6869
6870    Returns:
6871        Values: the Values expression object
6872    """
6873    if columns and not alias:
6874        raise ValueError("Alias is required when providing columns")
6875
6876    return Values(
6877        expressions=[convert(tup) for tup in values],
6878        alias=(
6879            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6880            if columns
6881            else (TableAlias(this=to_identifier(alias)) if alias else None)
6882        ),
6883    )

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:
6886def var(name: t.Optional[ExpOrStr]) -> Var:
6887    """Build a SQL variable.
6888
6889    Example:
6890        >>> repr(var('x'))
6891        'Var(this=x)'
6892
6893        >>> repr(var(column('x', table='y')))
6894        'Var(this=x)'
6895
6896    Args:
6897        name: The name of the var or an expression who's name will become the var.
6898
6899    Returns:
6900        The new variable node.
6901    """
6902    if not name:
6903        raise ValueError("Cannot convert empty name into var.")
6904
6905    if isinstance(name, Expression):
6906        name = name.name
6907    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table) -> AlterTable:
6910def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6911    """Build ALTER TABLE... RENAME... expression
6912
6913    Args:
6914        old_name: The old name of the table
6915        new_name: The new name of the table
6916
6917    Returns:
6918        Alter table expression
6919    """
6920    old_table = to_table(old_name)
6921    new_table = to_table(new_name)
6922    return AlterTable(
6923        this=old_table,
6924        actions=[
6925            RenameTable(this=new_table),
6926        ],
6927    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None) -> AlterTable:
6930def rename_column(
6931    table_name: str | Table,
6932    old_column_name: str | Column,
6933    new_column_name: str | Column,
6934    exists: t.Optional[bool] = None,
6935) -> AlterTable:
6936    """Build ALTER TABLE... RENAME COLUMN... expression
6937
6938    Args:
6939        table_name: Name of the table
6940        old_column: The old name of the column
6941        new_column: The new name of the column
6942        exists: Whether to add the `IF EXISTS` clause
6943
6944    Returns:
6945        Alter table expression
6946    """
6947    table = to_table(table_name)
6948    old_column = to_column(old_column_name)
6949    new_column = to_column(new_column_name)
6950    return AlterTable(
6951        this=table,
6952        actions=[
6953            RenameColumn(this=old_column, to=new_column, exists=exists),
6954        ],
6955    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6958def convert(value: t.Any, copy: bool = False) -> Expression:
6959    """Convert a python value into an expression object.
6960
6961    Raises an error if a conversion is not possible.
6962
6963    Args:
6964        value: A python object.
6965        copy: Whether to copy `value` (only applies to Expressions and collections).
6966
6967    Returns:
6968        Expression: the equivalent expression object.
6969    """
6970    if isinstance(value, Expression):
6971        return maybe_copy(value, copy)
6972    if isinstance(value, str):
6973        return Literal.string(value)
6974    if isinstance(value, bool):
6975        return Boolean(this=value)
6976    if value is None or (isinstance(value, float) and math.isnan(value)):
6977        return null()
6978    if isinstance(value, numbers.Number):
6979        return Literal.number(value)
6980    if isinstance(value, bytes):
6981        return HexString(this=value.hex())
6982    if isinstance(value, datetime.datetime):
6983        datetime_literal = Literal.string(
6984            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6985        )
6986        return TimeStrToTime(this=datetime_literal)
6987    if isinstance(value, datetime.date):
6988        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6989        return DateStrToDate(this=date_literal)
6990    if isinstance(value, tuple):
6991        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6992    if isinstance(value, list):
6993        return Array(expressions=[convert(v, copy=copy) for v in value])
6994    if isinstance(value, dict):
6995        return Map(
6996            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6997            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6998        )
6999    raise ValueError(f"Cannot convert {value}")

Convert a python value into an expression object.

Raises an error if a conversion is not possible.

Arguments:
  • value: A python object.
  • copy: Whether to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
7002def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7003    """
7004    Replace children of an expression with the result of a lambda fun(child) -> exp.
7005    """
7006    for k, v in tuple(expression.args.items()):
7007        is_list_arg = type(v) is list
7008
7009        child_nodes = v if is_list_arg else [v]
7010        new_child_nodes = []
7011
7012        for cn in child_nodes:
7013            if isinstance(cn, Expression):
7014                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7015                    new_child_nodes.append(child_node)
7016            else:
7017                new_child_nodes.append(cn)
7018
7019        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:
7022def replace_tree(
7023    expression: Expression,
7024    fun: t.Callable,
7025    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7026) -> Expression:
7027    """
7028    Replace an entire tree with the result of function calls on each node.
7029
7030    This will be traversed in reverse dfs, so leaves first.
7031    If new nodes are created as a result of function calls, they will also be traversed.
7032    """
7033    stack = list(expression.dfs(prune=prune))
7034
7035    while stack:
7036        node = stack.pop()
7037        new_node = fun(node)
7038
7039        if new_node is not node:
7040            node.replace(new_node)
7041
7042            if isinstance(new_node, Expression):
7043                stack.append(new_node)
7044
7045    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]:
7048def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7049    """
7050    Return all table names referenced through columns in an expression.
7051
7052    Example:
7053        >>> import sqlglot
7054        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7055        ['a', 'c']
7056
7057    Args:
7058        expression: expression to find table names.
7059        exclude: a table name to exclude
7060
7061    Returns:
7062        A list of unique names.
7063    """
7064    return {
7065        table
7066        for table in (column.table for column in expression.find_all(Column))
7067        if table and table != exclude
7068    }

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:
7071def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7072    """Get the full name of a table as a string.
7073
7074    Args:
7075        table: Table expression node or string.
7076        dialect: The dialect to generate the table name for.
7077        identify: Determines when an identifier should be quoted. Possible values are:
7078            False (default): Never quote, except in cases where it's mandatory by the dialect.
7079            True: Always quote.
7080
7081    Examples:
7082        >>> from sqlglot import exp, parse_one
7083        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7084        'a.b.c'
7085
7086    Returns:
7087        The table name.
7088    """
7089
7090    table = maybe_parse(table, into=Table, dialect=dialect)
7091
7092    if not table:
7093        raise ValueError(f"Cannot parse {table}")
7094
7095    return ".".join(
7096        (
7097            part.sql(dialect=dialect, identify=True, copy=False)
7098            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7099            else part.name
7100        )
7101        for part in table.parts
7102    )

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:
7105def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7106    """Returns a case normalized table name without quotes.
7107
7108    Args:
7109        table: the table to normalize
7110        dialect: the dialect to use for normalization rules
7111        copy: whether to copy the expression.
7112
7113    Examples:
7114        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7115        'A-B.c'
7116    """
7117    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7118
7119    return ".".join(
7120        p.name
7121        for p in normalize_identifiers(
7122            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7123        ).parts
7124    )

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:
7127def replace_tables(
7128    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7129) -> E:
7130    """Replace all tables in expression according to the mapping.
7131
7132    Args:
7133        expression: expression node to be transformed and replaced.
7134        mapping: mapping of table names.
7135        dialect: the dialect of the mapping table
7136        copy: whether to copy the expression.
7137
7138    Examples:
7139        >>> from sqlglot import exp, parse_one
7140        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7141        'SELECT * FROM c /* a.b */'
7142
7143    Returns:
7144        The mapped expression.
7145    """
7146
7147    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7148
7149    def _replace_tables(node: Expression) -> Expression:
7150        if isinstance(node, Table):
7151            original = normalize_table_name(node, dialect=dialect)
7152            new_name = mapping.get(original)
7153
7154            if new_name:
7155                table = to_table(
7156                    new_name,
7157                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7158                    dialect=dialect,
7159                )
7160                table.add_comments([original])
7161                return table
7162        return node
7163
7164    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:
7167def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7168    """Replace placeholders in an expression.
7169
7170    Args:
7171        expression: expression node to be transformed and replaced.
7172        args: positional names that will substitute unnamed placeholders in the given order.
7173        kwargs: keyword arguments that will substitute named placeholders.
7174
7175    Examples:
7176        >>> from sqlglot import exp, parse_one
7177        >>> replace_placeholders(
7178        ...     parse_one("select * from :tbl where ? = ?"),
7179        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7180        ... ).sql()
7181        "SELECT * FROM foo WHERE str_col = 'b'"
7182
7183    Returns:
7184        The mapped expression.
7185    """
7186
7187    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7188        if isinstance(node, Placeholder):
7189            if node.name:
7190                new_name = kwargs.get(node.name)
7191                if new_name is not None:
7192                    return convert(new_name)
7193            else:
7194                try:
7195                    return convert(next(args))
7196                except StopIteration:
7197                    pass
7198        return node
7199
7200    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:
7203def expand(
7204    expression: Expression,
7205    sources: t.Dict[str, Query],
7206    dialect: DialectType = None,
7207    copy: bool = True,
7208) -> Expression:
7209    """Transforms an expression by expanding all referenced sources into subqueries.
7210
7211    Examples:
7212        >>> from sqlglot import parse_one
7213        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7214        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7215
7216        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7217        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7218
7219    Args:
7220        expression: The expression to expand.
7221        sources: A dictionary of name to Queries.
7222        dialect: The dialect of the sources dict.
7223        copy: Whether to copy the expression during transformation. Defaults to True.
7224
7225    Returns:
7226        The transformed expression.
7227    """
7228    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7229
7230    def _expand(node: Expression):
7231        if isinstance(node, Table):
7232            name = normalize_table_name(node, dialect=dialect)
7233            source = sources.get(name)
7234            if source:
7235                subquery = source.subquery(node.alias or name)
7236                subquery.comments = [f"source: {name}"]
7237                return subquery.transform(_expand, copy=False)
7238        return node
7239
7240    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:
7243def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7244    """
7245    Returns a Func expression.
7246
7247    Examples:
7248        >>> func("abs", 5).sql()
7249        'ABS(5)'
7250
7251        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7252        'CAST(5 AS DOUBLE)'
7253
7254    Args:
7255        name: the name of the function to build.
7256        args: the args used to instantiate the function of interest.
7257        copy: whether to copy the argument expressions.
7258        dialect: the source dialect.
7259        kwargs: the kwargs used to instantiate the function of interest.
7260
7261    Note:
7262        The arguments `args` and `kwargs` are mutually exclusive.
7263
7264    Returns:
7265        An instance of the function of interest, or an anonymous function, if `name` doesn't
7266        correspond to an existing `sqlglot.expressions.Func` class.
7267    """
7268    if args and kwargs:
7269        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7270
7271    from sqlglot.dialects.dialect import Dialect
7272
7273    dialect = Dialect.get_or_raise(dialect)
7274
7275    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7276    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7277
7278    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7279    if constructor:
7280        if converted:
7281            if "dialect" in constructor.__code__.co_varnames:
7282                function = constructor(converted, dialect=dialect)
7283            else:
7284                function = constructor(converted)
7285        elif constructor.__name__ == "from_arg_list":
7286            function = constructor.__self__(**kwargs)  # type: ignore
7287        else:
7288            constructor = FUNCTION_BY_NAME.get(name.upper())
7289            if constructor:
7290                function = constructor(**kwargs)
7291            else:
7292                raise ValueError(
7293                    f"Unable to convert '{name}' into a Func. Either manually construct "
7294                    "the Func expression of interest or parse the function call."
7295                )
7296    else:
7297        kwargs = kwargs or {"expressions": converted}
7298        function = Anonymous(this=name, **kwargs)
7299
7300    for error_message in function.error_messages(converted):
7301        raise ValueError(error_message)
7302
7303    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:
7306def case(
7307    expression: t.Optional[ExpOrStr] = None,
7308    **opts,
7309) -> Case:
7310    """
7311    Initialize a CASE statement.
7312
7313    Example:
7314        case().when("a = 1", "foo").else_("bar")
7315
7316    Args:
7317        expression: Optionally, the input expression (not all dialects support this)
7318        **opts: Extra keyword arguments for parsing `expression`
7319    """
7320    if expression is not None:
7321        this = maybe_parse(expression, **opts)
7322    else:
7323        this = None
7324    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:
7327def cast_unless(
7328    expression: ExpOrStr,
7329    to: DATA_TYPE,
7330    *types: DATA_TYPE,
7331    **opts: t.Any,
7332) -> Expression | Cast:
7333    """
7334    Cast an expression to a data type unless it is a specified type.
7335
7336    Args:
7337        expression: The expression to cast.
7338        to: The data type to cast to.
7339        **types: The types to exclude from casting.
7340        **opts: Extra keyword arguments for parsing `expression`
7341    """
7342    expr = maybe_parse(expression, **opts)
7343    if expr.is_type(*types):
7344        return expr
7345    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:
7348def array(
7349    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7350) -> Array:
7351    """
7352    Returns an array.
7353
7354    Examples:
7355        >>> array(1, 'x').sql()
7356        'ARRAY(1, x)'
7357
7358    Args:
7359        expressions: the expressions to add to the array.
7360        copy: whether to copy the argument expressions.
7361        dialect: the source dialect.
7362        kwargs: the kwargs used to instantiate the function of interest.
7363
7364    Returns:
7365        An array expression.
7366    """
7367    return Array(
7368        expressions=[
7369            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7370            for expression in expressions
7371        ]
7372    )

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:
7375def tuple_(
7376    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7377) -> Tuple:
7378    """
7379    Returns an tuple.
7380
7381    Examples:
7382        >>> tuple_(1, 'x').sql()
7383        '(1, x)'
7384
7385    Args:
7386        expressions: the expressions to add to the tuple.
7387        copy: whether to copy the argument expressions.
7388        dialect: the source dialect.
7389        kwargs: the kwargs used to instantiate the function of interest.
7390
7391    Returns:
7392        A tuple expression.
7393    """
7394    return Tuple(
7395        expressions=[
7396            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7397            for expression in expressions
7398        ]
7399    )

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:
7402def true() -> Boolean:
7403    """
7404    Returns a true Boolean expression.
7405    """
7406    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7409def false() -> Boolean:
7410    """
7411    Returns a false Boolean expression.
7412    """
7413    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7416def null() -> Null:
7417    """
7418    Returns a Null expression.
7419    """
7420    return Null()

Returns a Null expression.

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