# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

""":py:class:`Expr` — the logical expression type used to build DataFusion queries.

An :py:class:`Expr` represents a computation over columns or literals: a
column reference (``col("a")``), a literal (``lit(5)``), an operator
combination (``col("a") + lit(1)``), or the output of a function from
:py:mod:`datafusion.functions`. Expressions are passed to
:py:class:`~datafusion.dataframe.DataFrame` methods such as
:py:meth:`~datafusion.dataframe.DataFrame.select`,
:py:meth:`~datafusion.dataframe.DataFrame.filter`,
:py:meth:`~datafusion.dataframe.DataFrame.aggregate`, and
:py:meth:`~datafusion.dataframe.DataFrame.sort`.

Convenience constructors are re-exported at the package level:
:py:func:`datafusion.col` / :py:func:`datafusion.column` for column references
and :py:func:`datafusion.lit` / :py:func:`datafusion.literal` for scalar
literals.

Examples:
    >>> ctx = dfn.SessionContext()
    >>> df = ctx.from_pydict({"a": [1, 2, 3]})
    >>> df.select((col("a") * lit(10)).alias("ten_a")).to_pydict()
    {'ten_a': [10, 20, 30]}

See :ref:`expressions` in the online documentation for details on available
operators and helpers.
"""

# ruff: noqa: PLC0415

from __future__ import annotations

from collections.abc import Callable, Iterable, Sequence
from typing import TYPE_CHECKING, Any, ClassVar

import pyarrow as pa

from ._internal import expr as expr_internal
from ._internal import functions as functions_internal
from .ipc import get_sender_ctx

if TYPE_CHECKING:
    from collections.abc import Sequence

    from datafusion.common import (  # type: ignore[import]
        DataTypeMap,
        NullTreatment,
        RexType,
    )
    from datafusion.context import SessionContext
    from datafusion.plan import LogicalPlan


# Standard error message for invalid expression types
# Mention both alias forms of column and literal helpers
EXPR_TYPE_ERROR = "Use col()/column() or lit()/literal() to construct expressions"

# The following are imported from the internal representation. We may choose to
# give these all proper wrappers, or to simply leave as is. These were added
# in order to support passing the `test_imports` unit test.
# Tim Saucer note: It is not clear to me what the use case is for exposing
# these definitions to the end user.

Alias = expr_internal.Alias
Analyze = expr_internal.Analyze
Aggregate = expr_internal.Aggregate
AggregateFunction = expr_internal.AggregateFunction
Between = expr_internal.Between
BinaryExpr = expr_internal.BinaryExpr
Case = expr_internal.Case
Cast = expr_internal.Cast
Column = expr_internal.Column
CopyTo = expr_internal.CopyTo
CreateCatalog = expr_internal.CreateCatalog
CreateCatalogSchema = expr_internal.CreateCatalogSchema
CreateExternalTable = expr_internal.CreateExternalTable
CreateFunction = expr_internal.CreateFunction
CreateFunctionBody = expr_internal.CreateFunctionBody
CreateIndex = expr_internal.CreateIndex
CreateMemoryTable = expr_internal.CreateMemoryTable
CreateView = expr_internal.CreateView
Deallocate = expr_internal.Deallocate
DescribeTable = expr_internal.DescribeTable
Distinct = expr_internal.Distinct
DmlStatement = expr_internal.DmlStatement
DropCatalogSchema = expr_internal.DropCatalogSchema
DropFunction = expr_internal.DropFunction
DropTable = expr_internal.DropTable
DropView = expr_internal.DropView
EmptyRelation = expr_internal.EmptyRelation
Execute = expr_internal.Execute
Exists = expr_internal.Exists
Explain = expr_internal.Explain
Extension = expr_internal.Extension
FileType = expr_internal.FileType
Filter = expr_internal.Filter
Join = expr_internal.Join
ILike = expr_internal.ILike
InList = expr_internal.InList
InSubquery = expr_internal.InSubquery
IsFalse = expr_internal.IsFalse
IsNotTrue = expr_internal.IsNotTrue
IsNull = expr_internal.IsNull
IsTrue = expr_internal.IsTrue
IsUnknown = expr_internal.IsUnknown
IsNotFalse = expr_internal.IsNotFalse
IsNotNull = expr_internal.IsNotNull
IsNotUnknown = expr_internal.IsNotUnknown
JoinConstraint = expr_internal.JoinConstraint
JoinType = expr_internal.JoinType
Like = expr_internal.Like
Limit = expr_internal.Limit
Literal = expr_internal.Literal
Negative = expr_internal.Negative
Not = expr_internal.Not
OperateFunctionArg = expr_internal.OperateFunctionArg
Partitioning = expr_internal.Partitioning
Placeholder = expr_internal.Placeholder
Prepare = expr_internal.Prepare
Projection = expr_internal.Projection
RecursiveQuery = expr_internal.RecursiveQuery
Repartition = expr_internal.Repartition
ScalarSubquery = expr_internal.ScalarSubquery
ScalarVariable = expr_internal.ScalarVariable
SetVariable = expr_internal.SetVariable
SimilarTo = expr_internal.SimilarTo
Sort = expr_internal.Sort
Subquery = expr_internal.Subquery
SubqueryAlias = expr_internal.SubqueryAlias
TableScan = expr_internal.TableScan
TransactionAccessMode = expr_internal.TransactionAccessMode
TransactionConclusion = expr_internal.TransactionConclusion
TransactionEnd = expr_internal.TransactionEnd
TransactionIsolationLevel = expr_internal.TransactionIsolationLevel
TransactionStart = expr_internal.TransactionStart
TryCast = expr_internal.TryCast
Union = expr_internal.Union
HigherOrderFunction = expr_internal.HigherOrderFunction
Lambda = expr_internal.Lambda
LambdaVariable = expr_internal.LambdaVariable
Unnest = expr_internal.Unnest
UnnestExpr = expr_internal.UnnestExpr
Values = expr_internal.Values
WindowExpr = expr_internal.WindowExpr

__all__ = [
    "EXPR_TYPE_ERROR",
    "Aggregate",
    "AggregateFunction",
    "Alias",
    "Analyze",
    "Between",
    "BinaryExpr",
    "Case",
    "CaseBuilder",
    "Cast",
    "Column",
    "CopyTo",
    "CreateCatalog",
    "CreateCatalogSchema",
    "CreateExternalTable",
    "CreateFunction",
    "CreateFunctionBody",
    "CreateIndex",
    "CreateMemoryTable",
    "CreateView",
    "Deallocate",
    "DescribeTable",
    "Distinct",
    "DmlStatement",
    "DropCatalogSchema",
    "DropFunction",
    "DropTable",
    "DropView",
    "EmptyRelation",
    "Execute",
    "Exists",
    "Explain",
    "Expr",
    "Extension",
    "FileType",
    "Filter",
    "GroupingSet",
    "HigherOrderFunction",
    "ILike",
    "InList",
    "InSubquery",
    "IsFalse",
    "IsNotFalse",
    "IsNotNull",
    "IsNotTrue",
    "IsNotUnknown",
    "IsNull",
    "IsTrue",
    "IsUnknown",
    "Join",
    "JoinConstraint",
    "JoinType",
    "Lambda",
    "LambdaVariable",
    "Like",
    "Limit",
    "Literal",
    "Literal",
    "Negative",
    "Not",
    "OperateFunctionArg",
    "Partitioning",
    "Placeholder",
    "Prepare",
    "Projection",
    "RecursiveQuery",
    "Repartition",
    "ScalarSubquery",
    "ScalarVariable",
    "SetVariable",
    "SimilarTo",
    "Sort",
    "SortExpr",
    "SortKey",
    "Subquery",
    "SubqueryAlias",
    "TableScan",
    "TransactionAccessMode",
    "TransactionConclusion",
    "TransactionEnd",
    "TransactionIsolationLevel",
    "TransactionStart",
    "TryCast",
    "Union",
    "Unnest",
    "UnnestExpr",
    "Values",
    "Window",
    "WindowExpr",
    "WindowFrame",
    "WindowFrameBound",
    "coerce_to_expr",
    "coerce_to_expr_or_none",
    "ensure_expr",
    "ensure_expr_list",
]


def ensure_expr(value: Expr | Any) -> expr_internal.Expr:
    """Return the internal expression from ``Expr`` or raise ``TypeError``.

    This helper rejects plain strings and other non-:class:`Expr` values so
    higher level APIs consistently require explicit :func:`~datafusion.col` or
    :func:`~datafusion.lit` expressions.

    See Also:
        :func:`coerce_to_expr` — the opposite behavior: *wraps* non-``Expr``
        values as literals instead of rejecting them.

    Args:
        value: Candidate expression or other object.

    Returns:
        The internal expression representation.

    Raises:
        TypeError: If ``value`` is not an instance of :class:`Expr`.
    """
    if not isinstance(value, Expr):
        raise TypeError(EXPR_TYPE_ERROR)
    return value.expr


def ensure_expr_list(
    exprs: Iterable[Expr | Iterable[Expr]],
) -> list[expr_internal.Expr]:
    """Flatten an iterable of expressions, validating each via ``ensure_expr``.

    Args:
        exprs: Possibly nested iterable containing expressions.

    Returns:
        A flat list of raw expressions.

    Raises:
        TypeError: If any item is not an instance of :class:`Expr`.
    """

    def _iter(
        items: Iterable[Expr | Iterable[Expr]],
    ) -> Iterable[expr_internal.Expr]:
        for expr in items:
            if isinstance(expr, Iterable) and not isinstance(
                expr, Expr | str | bytes | bytearray
            ):
                # Treat string-like objects as atomic to surface standard errors
                yield from _iter(expr)
            else:
                yield ensure_expr(expr)

    return list(_iter(exprs))


def coerce_to_expr(value: Any) -> Expr:
    """Coerce a native Python value to an ``Expr`` literal, passing ``Expr`` through.

    This is the complement of :func:`ensure_expr`: where ``ensure_expr``
    *rejects* non-``Expr`` values, ``coerce_to_expr`` *wraps* them via
    :meth:`Expr.literal` so that functions can accept native Python types
    (``int``, ``float``, ``str``, ``bool``, etc.) alongside ``Expr``.

    Args:
        value: An ``Expr`` instance (returned as-is) or a Python literal to wrap.

    Returns:
        An ``Expr`` representing the value.
    """
    if isinstance(value, Expr):
        return value
    return Expr.literal(value)


def coerce_to_expr_or_none(value: Any | None) -> Expr | None:
    """Coerce a value to ``Expr`` or pass ``None`` through unchanged.

    Same as :func:`coerce_to_expr` but accepts ``None`` for optional parameters.

    Args:
        value: An ``Expr`` instance, a Python literal to wrap, or ``None``.

    Returns:
        An ``Expr`` representing the value, or ``None``.
    """
    if value is None:
        return None
    return coerce_to_expr(value)


def _to_raw_expr(value: Expr | str) -> expr_internal.Expr:
    """Convert a Python expression or column name to its raw variant.

    Args:
        value: Candidate expression or column name.

    Returns:
        The internal :class:`~datafusion._internal.expr.Expr` representation.

    Raises:
        TypeError: If ``value`` is neither an :class:`Expr` nor ``str``.
    """
    if isinstance(value, str):
        return Expr.column(value).expr
    if isinstance(value, Expr):
        return value.expr
    error = (
        "Expected Expr or column name, found:"
        f" {type(value).__name__}. {EXPR_TYPE_ERROR}."
    )
    raise TypeError(error)


def expr_list_to_raw_expr_list(
    expr_list: list[Expr] | Expr | None,
) -> list[expr_internal.Expr] | None:
    """Convert a sequence of expressions or column names to raw expressions."""
    if isinstance(expr_list, Expr | str):
        expr_list = [expr_list]
    if expr_list is None:
        return None
    return [_to_raw_expr(e) for e in expr_list]


def sort_or_default(e: Expr | SortExpr) -> expr_internal.SortExpr:
    """Helper function to return a default Sort if an Expr is provided."""
    if isinstance(e, SortExpr):
        return e.raw_sort
    return SortExpr(e, ascending=True, nulls_first=True).raw_sort


def sort_list_to_raw_sort_list(
    sort_list: Sequence[SortKey] | SortKey | None,
) -> list[expr_internal.SortExpr] | None:
    """Helper function to return an optional sort list to raw variant."""
    if isinstance(sort_list, Expr | SortExpr | str):
        sort_list = [sort_list]
    if sort_list is None:
        return None
    raw_sort_list = []
    for item in sort_list:
        if isinstance(item, SortExpr):
            raw_sort_list.append(sort_or_default(item))
        else:
            raw_expr = _to_raw_expr(item)  # may raise ``TypeError``
            raw_sort_list.append(sort_or_default(Expr(raw_expr)))
    return raw_sort_list


class Expr:  # noqa: PLW1641
    """Expression object.

    Expressions are one of the core concepts in DataFusion. See
    :ref:`Expressions` in the online documentation for more information.
    """

    def __init__(self, expr: expr_internal.RawExpr) -> None:
        """This constructor should not be called by the end user."""
        self.expr = expr

    def to_variant(self) -> Any:
        """Convert this expression into a python object if possible."""
        return self.expr.to_variant()

    def schema_name(self) -> str:
        """Returns the name of this expression as it should appear in a schema.

        This name will not include any CAST expressions.
        """
        return self.expr.schema_name()

    def canonical_name(self) -> str:
        """Returns a complete string representation of this expression."""
        return self.expr.canonical_name()

    def variant_name(self) -> str:
        """Returns the name of the Expr variant.

        Ex: ``IsNotNull``, ``Literal``, ``BinaryExpr``, etc
        """
        return self.expr.variant_name()

    def to_bytes(self, ctx: SessionContext | None = None) -> bytes:
        """Serialize this expression to bytes for shipping to another process.

        Use this — or :func:`pickle.dumps` — to send an expression to a
        worker process for distributed evaluation.

        When ``ctx`` is supplied, encoding routes through that session's
        installed :class:`LogicalExtensionCodec` (so settings like
        :meth:`SessionContext.with_python_udf_inlining` take effect).
        When ``ctx`` is ``None``, the default codec is used (Python UDF
        inlining on, no user-installed extension codec).

        Built-in functions travel inside the returned bytes. Python UDFs
        (scalar, aggregate, window) also inline by default, so the worker
        does not need to pre-register them; when the encoding session has
        :meth:`SessionContext.with_python_udf_inlining` set to ``False``,
        Python UDFs travel by name only and must be registered on the
        worker. UDFs imported via the FFI capsule protocol always travel
        by name only and must be registered on the worker.

        .. warning:: Security
            Bytes returned here may embed a cloudpickled Python
            callable (when the expression carries a Python UDF).
            Reconstructing them via :meth:`from_bytes` or
            :func:`pickle.loads` executes arbitrary Python on the
            receiver. Only accept payloads from trusted sources.

        .. warning:: Portability
            cloudpickle serializes Python bytecode, which is **not
            stable across Python minor versions**. A payload produced
            on Python 3.11 will fail to load on Python 3.12. The
            wire format stamps the sender's ``(major, minor)``;
            :meth:`from_bytes` raises a :class:`ValueError` naming
            both versions on mismatch.

            cloudpickle captures the UDF callable **by value** —
            bytecode and closure cells inlined — but names the
            callable resolves via ``import`` are captured **by
            reference** (module path only) and must be importable on
            the receiver.

            **Self-contained — works anywhere:**

            .. code-block:: python

                # Lambda: bytecode captured inline
                udf(lambda x: x * 2, [pa.int64()], pa.int64(),
                    volatility="immutable")

                # Locally-defined function: bytecode captured inline
                def double(x):
                    return x * 2
                udf(double, [pa.int64()], pa.int64(), volatility="immutable")

                # Closure over a local variable: value captured inline
                factor = 3
                udf(lambda x: x * factor, [pa.int64()], pa.int64(),
                    volatility="immutable")

            **Requires matching environment on receiver:**

            .. code-block:: python

                # Top-level import: `foo` must be installed on receiver
                from foo import double
                udf(double, [pa.int64()], pa.int64(), volatility="immutable")

                # Bound method of an imported class: same caveat
                from mylib import Transformer
                t = Transformer()
                udf(t.transform, [pa.int64()], pa.int64(),
                    volatility="immutable")

        Examples:
            >>> from datafusion import col, lit
            >>> blob = (col("a") + lit(1)).to_bytes()
            >>> isinstance(blob, bytes)
            True
        """
        ctx_arg = ctx.ctx if ctx is not None else None
        return self.expr.to_bytes(ctx_arg)

    @classmethod
    def from_bytes(cls, buf: bytes, ctx: SessionContext | None = None) -> Expr:
        """Reconstruct an expression from serialized bytes.

        Accepts output of :meth:`to_bytes` or :func:`pickle.dumps`.
        ``ctx`` is the :class:`SessionContext` used to resolve any
        function references that travel by name (e.g. FFI UDFs, or
        Python UDFs sent with inlining disabled via
        :meth:`SessionContext.with_python_udf_inlining`). When
        ``ctx`` is ``None`` the worker context installed via
        :func:`datafusion.ipc.set_worker_ctx` is consulted; if no worker
        context is installed, the global :class:`SessionContext` is used
        (sufficient for built-ins and Python UDFs, plus any UDFs
        registered on the global context).

        .. warning:: Security
            Decoding may invoke ``cloudpickle.loads`` on bytes embedded
            in the payload, which executes arbitrary Python code. Treat
            ``buf`` as code, not data — only decode bytes you produced
            yourself or received from a trusted sender.

        .. warning:: Portability
            cloudpickle payloads are **not portable across Python
            minor versions**. The wire format stamps the sender's
            ``(major, minor)``; if it does not match the current
            interpreter, this method raises :class:`ValueError`
            naming both versions. Modules the UDF imports must also
            be importable on the receiver — see :meth:`to_bytes` for
            by-value vs. by-reference details.

        Examples:
            >>> from datafusion import Expr, col, lit
            >>> blob = (col("a") + lit(1)).to_bytes()
            >>> Expr.from_bytes(blob).canonical_name()
            'a + Int64(1)'
        """
        from datafusion.ipc import _resolve_ctx

        resolved = _resolve_ctx(ctx)
        return cls(expr_internal.RawExpr.from_bytes(resolved.ctx, buf))

    def __reduce__(self) -> tuple[Callable[[bytes], Expr], tuple[bytes]]:
        """Pickle protocol hook.

        Lets expressions be shipped to worker processes via
        :func:`pickle.dumps` / :func:`pickle.loads`. Built-in functions
        and Python UDFs (scalar, aggregate, window) travel inside the
        pickle bytes; only FFI-capsule UDFs require pre-registration on
        the worker. The worker's :class:`SessionContext` for resolving
        those references is looked up via
        :func:`datafusion.ipc.set_worker_ctx`, falling back to the
        global :class:`SessionContext` if none has been installed on
        the worker.

        .. warning:: Security
            :func:`pickle.loads` on the returned tuple executes
            arbitrary Python on the receiver, including any
            cloudpickled UDF callable embedded in the payload. Only
            unpickle expressions from trusted sources.

        .. warning:: Portability
            Sender and receiver must run the same Python
            ``(major, minor)`` version; cloudpickle bytecode is not
            portable across minor versions. See :meth:`to_bytes` for
            details on what travels by value vs. by reference.

        Examples:
            >>> import pickle
            >>> from datafusion import col, lit
            >>> e = col("a") * lit(2)
            >>> pickle.loads(pickle.dumps(e)).canonical_name()
            'a * Int64(2)'

        The encoding side honors a driver-side sender context installed
        via :func:`datafusion.ipc.set_sender_ctx` — that is how
        :meth:`SessionContext.with_python_udf_inlining` propagates
        through ``pickle.dumps``. The sender context is read by
        ``__reduce__``, so :func:`copy.copy` and :func:`copy.deepcopy`
        — which also go through ``__reduce__`` — pick it up too.
        """
        return (Expr._reconstruct, (self.to_bytes(get_sender_ctx()),))

    @classmethod
    def _reconstruct(cls, proto_bytes: bytes) -> Expr:
        """Internal entry point used by :meth:`__reduce__` on unpickle.

        Examples:
            >>> from datafusion import Expr, col, lit
            >>> blob = (col("a") + lit(1)).to_bytes()
            >>> Expr._reconstruct(blob).canonical_name()
            'a + Int64(1)'
        """
        return cls.from_bytes(proto_bytes)

    def __richcmp__(self, other: Expr, op: int) -> Expr:
        """Comparison operator."""
        return Expr(self.expr.__richcmp__(other.expr, op))

    def __repr__(self) -> str:
        """Generate a string representation of this expression."""
        return self.expr.__repr__()

    def __add__(self, rhs: Any) -> Expr:
        """Addition operator.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__add__(rhs.expr))

    def __sub__(self, rhs: Any) -> Expr:
        """Subtraction operator.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__sub__(rhs.expr))

    def __truediv__(self, rhs: Any) -> Expr:
        """Division operator.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__truediv__(rhs.expr))

    def __mul__(self, rhs: Any) -> Expr:
        """Multiplication operator.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__mul__(rhs.expr))

    def __mod__(self, rhs: Any) -> Expr:
        """Modulo operator (%).

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__mod__(rhs.expr))

    def __and__(self, rhs: Expr) -> Expr:
        """Logical AND."""
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__and__(rhs.expr))

    def __or__(self, rhs: Expr) -> Expr:
        """Logical OR."""
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__or__(rhs.expr))

    def __invert__(self) -> Expr:
        """Binary not (~)."""
        return Expr(self.expr.__invert__())

    def __getitem__(self, key: str | int) -> Expr:
        """Retrieve sub-object.

        If ``key`` is a string, returns the subfield of the struct.
        If ``key`` is an integer, retrieves the element in the array. Note that the
        element index begins at ``0``, unlike
        :py:func:`~datafusion.functions.array_element` which begins at ``1``.
        If ``key`` is a slice, returns an array that contains a slice of the
        original array. Similar to integer indexing, this follows Python convention
        where the index begins at ``0`` unlike
        :py:func:`~datafusion.functions.array_slice` which begins at ``1``.
        """
        if isinstance(key, int):
            return Expr(
                functions_internal.array_element(self.expr, Expr.literal(key + 1).expr)
            )
        if isinstance(key, slice):
            if isinstance(key.start, int):
                start = Expr.literal(key.start + 1).expr
            elif isinstance(key.start, Expr):
                start = (key.start + Expr.literal(1)).expr
            else:
                # Default start at the first element, index 1
                start = Expr.literal(1).expr

            if isinstance(key.stop, int):
                stop = Expr.literal(key.stop).expr
            else:
                stop = key.stop.expr

            if isinstance(key.step, int):
                step = Expr.literal(key.step).expr
            elif isinstance(key.step, Expr):
                step = key.step.expr
            else:
                step = key.step

            return Expr(functions_internal.array_slice(self.expr, start, stop, step))
        return Expr(self.expr.__getitem__(key))

    def __eq__(self, rhs: object) -> Expr:
        """Equal to.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if rhs is None:
            return self.is_null()
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__eq__(rhs.expr))

    def __ne__(self, rhs: object) -> Expr:
        """Not equal to.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if rhs is None:
            return self.is_not_null()
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__ne__(rhs.expr))

    def __ge__(self, rhs: Any) -> Expr:
        """Greater than or equal to.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__ge__(rhs.expr))

    def __gt__(self, rhs: Any) -> Expr:
        """Greater than.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__gt__(rhs.expr))

    def __le__(self, rhs: Any) -> Expr:
        """Less than or equal to.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__le__(rhs.expr))

    def __lt__(self, rhs: Any) -> Expr:
        """Less than.

        Accepts either an expression or any valid PyArrow scalar literal value.
        """
        if not isinstance(rhs, Expr):
            rhs = Expr.literal(rhs)
        return Expr(self.expr.__lt__(rhs.expr))

    __radd__ = __add__
    __rand__ = __and__
    __rmod__ = __mod__
    __rmul__ = __mul__
    __ror__ = __or__
    __rsub__ = __sub__
    __rtruediv__ = __truediv__

    @staticmethod
    def literal(value: Any) -> Expr:
        """Creates a new expression representing a scalar value.

        ``value`` must be a valid PyArrow scalar value or easily castable to one.
        """
        if isinstance(value, str):
            value = pa.scalar(value, type=pa.string_view())
        return Expr(expr_internal.RawExpr.literal(value))

    @staticmethod
    def literal_with_metadata(value: Any, metadata: dict[str, str]) -> Expr:
        """Creates a new expression representing a scalar value with metadata.

        Args:
            value: A valid PyArrow scalar value or easily castable to one.
            metadata: Metadata to attach to the expression.
        """
        if isinstance(value, str):
            value = pa.scalar(value, type=pa.string_view())

        return Expr(expr_internal.RawExpr.literal_with_metadata(value, metadata))

    @staticmethod
    def string_literal(value: str) -> Expr:
        """Creates a new expression representing a UTF8 literal value.

        It is different from `literal` because it is pa.string() instead of
        pa.string_view()

        This is needed for cases where DataFusion is expecting a UTF8 instead of
        UTF8View literal, like in:
        https://github.com/apache/datafusion/blob/86740bfd3d9831d6b7c1d0e1bf4a21d91598a0ac/datafusion/functions/src/core/arrow_cast.rs#L179
        """
        if isinstance(value, str):
            value = pa.scalar(value, type=pa.string())
            return Expr(expr_internal.RawExpr.literal(value))
        return Expr.literal(value)

    @staticmethod
    def column(value: str) -> Expr:
        """Creates a new expression representing a column."""
        return Expr(expr_internal.RawExpr.column(value))

    def alias(self, name: str, metadata: dict[str, str] | None = None) -> Expr:
        """Assign a name to the expression.

        Args:
            name: The name to assign to the expression.
            metadata: Optional metadata to attach to the expression.

        Returns:
            A new expression with the assigned name.
        """
        return Expr(self.expr.alias(name, metadata))

    def sort(self, ascending: bool = True, nulls_first: bool = True) -> SortExpr:
        """Creates a sort :py:class:`Expr` from an existing :py:class:`Expr`.

        Args:
            ascending: If true, sort in ascending order.
            nulls_first: Return null values first.
        """
        return SortExpr(self, ascending=ascending, nulls_first=nulls_first)

    def is_null(self) -> Expr:
        """Returns ``True`` if this expression is null."""
        return Expr(self.expr.is_null())

    def is_not_null(self) -> Expr:
        """Returns ``True`` if this expression is not null."""
        return Expr(self.expr.is_not_null())

    def fill_nan(self, value: Any | Expr | None = None) -> Expr:
        """Fill NaN values with a provided value."""
        if not isinstance(value, Expr):
            value = Expr.literal(value)
        return Expr(functions_internal.nanvl(self.expr, value.expr))

    def fill_null(self, value: Any | Expr | None = None) -> Expr:
        """Fill NULL values with a provided value."""
        if not isinstance(value, Expr):
            value = Expr.literal(value)
        return Expr(functions_internal.nvl(self.expr, value.expr))

    _to_pyarrow_types: ClassVar[dict[type, pa.DataType]] = {
        float: pa.float64(),
        int: pa.int64(),
        str: pa.string(),
        bool: pa.bool_(),
    }

    def cast(self, to: pa.DataType[Any] | type) -> Expr:
        """Cast to a new data type."""
        if not isinstance(to, pa.DataType):
            try:
                to = self._to_pyarrow_types[to]
            except KeyError as err:
                error_msg = "Expected instance of pyarrow.DataType or builtins.type"
                raise TypeError(error_msg) from err

        return Expr(self.expr.cast(to))

    def try_cast(self, to: pa.DataType[Any] | type) -> Expr:
        """Cast to a new data type, returning NULL on failure.

        Like :py:meth:`cast` but produces NULL instead of erroring when the
        cast cannot be performed for a given row.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": ["oops"]})
            >>> result = df.select(col("a").try_cast(pa.float64()).alias("c"))
            >>> result.collect_column("c")[0].as_py() is None
            True
        """
        if not isinstance(to, pa.DataType):
            try:
                to = self._to_pyarrow_types[to]
            except KeyError as err:
                error_msg = "Expected instance of pyarrow.DataType or builtins.type"
                raise TypeError(error_msg) from err

        return Expr(self.expr.try_cast(to))

    def between(self, low: Any, high: Any, negated: bool = False) -> Expr:
        """Returns ``True`` if this expression is between a given range.

        Args:
            low: lower bound of the range (inclusive).
            high: higher bound of the range (inclusive).
            negated: negates whether the expression is between a given range
        """
        if not isinstance(low, Expr):
            low = Expr.literal(low)

        if not isinstance(high, Expr):
            high = Expr.literal(high)

        return Expr(self.expr.between(low.expr, high.expr, negated=negated))

    def rex_type(self) -> RexType:
        """Return the Rex Type of this expression.

        A Rex (Row Expression) specifies a single row of data.That specification
        could include user defined functions or types. RexType identifies the
        row as one of the possible valid ``RexType``.
        """
        return self.expr.rex_type()

    def types(self) -> DataTypeMap:
        """Return the ``DataTypeMap``.

        Returns:
            DataTypeMap which represents the PythonType, Arrow DataType, and
            SqlType Enum which this expression represents.
        """
        return self.expr.types()

    def python_value(self) -> Any:
        """Extracts the Expr value into `Any`.

        This is only valid for literal expressions.

        Returns:
            Python object representing literal value of the expression.
        """
        return self.expr.python_value()

    def rex_call_operands(self) -> list[Expr]:
        """Return the operands of the expression based on it's variant type.

        Row expressions, Rex(s), operate on the concept of operands. Different
        variants of Expressions, Expr(s), store those operands in different
        datastructures. This function examines the Expr variant and returns
        the operands to the calling logic.
        """
        return [Expr(e) for e in self.expr.rex_call_operands()]

    def rex_call_operator(self) -> str:
        """Extracts the operator associated with a row expression type call."""
        return self.expr.rex_call_operator()

    def column_name(self, plan: LogicalPlan) -> str:
        """Compute the output column name based on the provided logical plan."""
        return self.expr.column_name(plan._raw_plan)

    def order_by(self, *exprs: Expr | SortExpr) -> ExprFuncBuilder:
        """Set the ordering for a window or aggregate function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.order_by([sort_or_default(e) for e in exprs]))

    def filter(self, filter: Expr) -> ExprFuncBuilder:
        """Filter an aggregate function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.filter(filter.expr))

    def distinct(self) -> ExprFuncBuilder:
        """Only evaluate distinct values for an aggregate function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.distinct())

    def null_treatment(self, null_treatment: NullTreatment) -> ExprFuncBuilder:
        """Set the treatment for ``null`` values for a window or aggregate function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.null_treatment(null_treatment.value))

    def partition_by(self, *partition_by: Expr) -> ExprFuncBuilder:
        """Set the partitioning for a window function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.partition_by([e.expr for e in partition_by]))

    def window_frame(self, window_frame: WindowFrame) -> ExprFuncBuilder:
        """Set the frame fora  window function.

        This function will create an :py:class:`ExprFuncBuilder` that can be used to
        set parameters for either window or aggregate functions. If used on any other
        type of expression, an error will be generated when ``build()`` is called.
        """
        return ExprFuncBuilder(self.expr.window_frame(window_frame.window_frame))

    def over(self, window: Window) -> Expr:
        """Turn an aggregate function into a window function.

        This function turns any aggregate function into a window function. With the
        exception of ``partition_by``, how each of the parameters is used is determined
        by the underlying aggregate function.

        Args:
            window: Window definition
        """
        partition_by_raw = expr_list_to_raw_expr_list(window._partition_by)
        order_by_raw = window._order_by
        window_frame_raw = (
            window._window_frame.window_frame
            if window._window_frame is not None
            else None
        )
        null_treatment_raw = (
            window._null_treatment.value if window._null_treatment is not None else None
        )

        return Expr(
            self.expr.over(
                partition_by=partition_by_raw,
                order_by=order_by_raw,
                window_frame=window_frame_raw,
                null_treatment=null_treatment_raw,
            )
        )

    def asin(self) -> Expr:
        """Returns the arc sine or inverse sine of a number."""
        from . import functions as F

        return F.asin(self)

    def array_pop_back(self) -> Expr:
        """Returns the array without the last element."""
        from . import functions as F

        return F.array_pop_back(self)

    def reverse(self) -> Expr:
        """Reverse the string argument."""
        from . import functions as F

        return F.reverse(self)

    def bit_length(self) -> Expr:
        """Returns the number of bits in the string argument."""
        from . import functions as F

        return F.bit_length(self)

    def array_length(self) -> Expr:
        """Returns the length of the array."""
        from . import functions as F

        return F.array_length(self)

    def array_ndims(self) -> Expr:
        """Returns the number of dimensions of the array."""
        from . import functions as F

        return F.array_ndims(self)

    def to_hex(self) -> Expr:
        """Converts an integer to a hexadecimal string."""
        from . import functions as F

        return F.to_hex(self)

    def array_dims(self) -> Expr:
        """Returns an array of the array's dimensions."""
        from . import functions as F

        return F.array_dims(self)

    def from_unixtime(self) -> Expr:
        """Converts an integer to RFC3339 timestamp format string."""
        from . import functions as F

        return F.from_unixtime(self)

    def array_empty(self) -> Expr:
        """Returns a boolean indicating whether the array is empty."""
        from . import functions as F

        return F.array_empty(self)

    def sin(self) -> Expr:
        """Returns the sine of the argument."""
        from . import functions as F

        return F.sin(self)

    def log10(self) -> Expr:
        """Base 10 logarithm of the argument."""
        from . import functions as F

        return F.log10(self)

    def initcap(self) -> Expr:
        """Set the initial letter of each word to capital.

        Converts the first letter of each word in ``string`` to uppercase and the
        remaining characters to lowercase.
        """
        from . import functions as F

        return F.initcap(self)

    def list_distinct(self) -> Expr:
        """Returns distinct values from the array after removing duplicates.

        This is an alias for :py:func:`array_distinct`.
        """
        from . import functions as F

        return F.list_distinct(self)

    def iszero(self) -> Expr:
        """Returns true if a given number is +0.0 or -0.0 otherwise returns false."""
        from . import functions as F

        return F.iszero(self)

    def array_distinct(self) -> Expr:
        """Returns distinct values from the array after removing duplicates."""
        from . import functions as F

        return F.array_distinct(self)

    def arrow_typeof(self) -> Expr:
        """Returns the Arrow type of the expression."""
        from . import functions as F

        return F.arrow_typeof(self)

    def length(self) -> Expr:
        """The number of characters in the ``string``."""
        from . import functions as F

        return F.length(self)

    def lower(self) -> Expr:
        """Converts a string to lowercase."""
        from . import functions as F

        return F.lower(self)

    def acos(self) -> Expr:
        """Returns the arc cosine or inverse cosine of a number.

        Returns:
        --------
        Expr
            A new expression representing the arc cosine of the input expression.
        """
        from . import functions as F

        return F.acos(self)

    def ascii(self) -> Expr:
        """Returns the numeric code of the first character of the argument."""
        from . import functions as F

        return F.ascii(self)

    def sha384(self) -> Expr:
        """Computes the SHA-384 hash of a binary string."""
        from . import functions as F

        return F.sha384(self)

    def isnan(self) -> Expr:
        """Returns true if a given number is +NaN or -NaN otherwise returns false."""
        from . import functions as F

        return F.isnan(self)

    def degrees(self) -> Expr:
        """Converts the argument from radians to degrees."""
        from . import functions as F

        return F.degrees(self)

    def cardinality(self) -> Expr:
        """Returns the total number of elements in the array."""
        from . import functions as F

        return F.cardinality(self)

    def sha224(self) -> Expr:
        """Computes the SHA-224 hash of a binary string."""
        from . import functions as F

        return F.sha224(self)

    def asinh(self) -> Expr:
        """Returns inverse hyperbolic sine."""
        from . import functions as F

        return F.asinh(self)

    def flatten(self) -> Expr:
        """Flattens an array of arrays into a single array."""
        from . import functions as F

        return F.flatten(self)

    def exp(self) -> Expr:
        """Returns the exponential of the argument."""
        from . import functions as F

        return F.exp(self)

    def abs(self) -> Expr:
        """Return the absolute value of a given number.

        Returns:
        --------
        Expr
            A new expression representing the absolute value of the input expression.
        """
        from . import functions as F

        return F.abs(self)

    def btrim(self) -> Expr:
        """Removes all characters, spaces by default, from both sides of a string."""
        from . import functions as F

        return F.btrim(self)

    def md5(self) -> Expr:
        """Computes an MD5 128-bit checksum for a string expression."""
        from . import functions as F

        return F.md5(self)

    def octet_length(self) -> Expr:
        """Returns the number of bytes of a string."""
        from . import functions as F

        return F.octet_length(self)

    def cosh(self) -> Expr:
        """Returns the hyperbolic cosine of the argument."""
        from . import functions as F

        return F.cosh(self)

    def radians(self) -> Expr:
        """Converts the argument from degrees to radians."""
        from . import functions as F

        return F.radians(self)

    def sqrt(self) -> Expr:
        """Returns the square root of the argument."""
        from . import functions as F

        return F.sqrt(self)

    def character_length(self) -> Expr:
        """Returns the number of characters in the argument."""
        from . import functions as F

        return F.character_length(self)

    def tanh(self) -> Expr:
        """Returns the hyperbolic tangent of the argument."""
        from . import functions as F

        return F.tanh(self)

    def atan(self) -> Expr:
        """Returns inverse tangent of a number."""
        from . import functions as F

        return F.atan(self)

    def rtrim(self) -> Expr:
        """Removes all characters, spaces by default, from the end of a string."""
        from . import functions as F

        return F.rtrim(self)

    def atanh(self) -> Expr:
        """Returns inverse hyperbolic tangent."""
        from . import functions as F

        return F.atanh(self)

    def list_dims(self) -> Expr:
        """Returns an array of the array's dimensions.

        This is an alias for :py:func:`array_dims`.
        """
        from . import functions as F

        return F.list_dims(self)

    def sha256(self) -> Expr:
        """Computes the SHA-256 hash of a binary string."""
        from . import functions as F

        return F.sha256(self)

    def factorial(self) -> Expr:
        """Returns the factorial of the argument."""
        from . import functions as F

        return F.factorial(self)

    def acosh(self) -> Expr:
        """Returns inverse hyperbolic cosine."""
        from . import functions as F

        return F.acosh(self)

    def floor(self) -> Expr:
        """Returns the nearest integer less than or equal to the argument."""
        from . import functions as F

        return F.floor(self)

    def ceil(self) -> Expr:
        """Returns the nearest integer greater than or equal to argument."""
        from . import functions as F

        return F.ceil(self)

    def list_length(self) -> Expr:
        """Returns the length of the array.

        This is an alias for :py:func:`array_length`.
        """
        from . import functions as F

        return F.list_length(self)

    def upper(self) -> Expr:
        """Converts a string to uppercase."""
        from . import functions as F

        return F.upper(self)

    def chr(self) -> Expr:
        """Converts the Unicode code point to a UTF8 character."""
        from . import functions as F

        return F.chr(self)

    def ln(self) -> Expr:
        """Returns the natural logarithm (base e) of the argument."""
        from . import functions as F

        return F.ln(self)

    def tan(self) -> Expr:
        """Returns the tangent of the argument."""
        from . import functions as F

        return F.tan(self)

    def array_pop_front(self) -> Expr:
        """Returns the array without the first element."""
        from . import functions as F

        return F.array_pop_front(self)

    def cbrt(self) -> Expr:
        """Returns the cube root of a number."""
        from . import functions as F

        return F.cbrt(self)

    def sha512(self) -> Expr:
        """Computes the SHA-512 hash of a binary string."""
        from . import functions as F

        return F.sha512(self)

    def char_length(self) -> Expr:
        """The number of characters in the ``string``."""
        from . import functions as F

        return F.char_length(self)

    def list_ndims(self) -> Expr:
        """Returns the number of dimensions of the array.

        This is an alias for :py:func:`array_ndims`.
        """
        from . import functions as F

        return F.list_ndims(self)

    def trim(self) -> Expr:
        """Removes all characters, spaces by default, from both sides of a string."""
        from . import functions as F

        return F.trim(self)

    def cos(self) -> Expr:
        """Returns the cosine of the argument."""
        from . import functions as F

        return F.cos(self)

    def sinh(self) -> Expr:
        """Returns the hyperbolic sine of the argument."""
        from . import functions as F

        return F.sinh(self)

    def empty(self) -> Expr:
        """This is an alias for :py:func:`array_empty`."""
        from . import functions as F

        return F.empty(self)

    def ltrim(self) -> Expr:
        """Removes all characters, spaces by default, from the beginning of a string."""
        from . import functions as F

        return F.ltrim(self)

    def signum(self) -> Expr:
        """Returns the sign of the argument (-1, 0, +1)."""
        from . import functions as F

        return F.signum(self)

    def log2(self) -> Expr:
        """Base 2 logarithm of the argument."""
        from . import functions as F

        return F.log2(self)

    def cot(self) -> Expr:
        """Returns the cotangent of the argument."""
        from . import functions as F

        return F.cot(self)


class ExprFuncBuilder:
    def __init__(self, builder: expr_internal.ExprFuncBuilder) -> None:
        self.builder = builder

    def order_by(self, *exprs: Expr) -> ExprFuncBuilder:
        """Set the ordering for a window or aggregate function.

        Values given in ``exprs`` must be sort expressions. You can convert any other
        expression to a sort expression using `.sort()`.
        """
        return ExprFuncBuilder(
            self.builder.order_by([sort_or_default(e) for e in exprs])
        )

    def filter(self, filter: Expr) -> ExprFuncBuilder:
        """Filter values during aggregation."""
        return ExprFuncBuilder(self.builder.filter(filter.expr))

    def distinct(self) -> ExprFuncBuilder:
        """Only evaluate distinct values during aggregation."""
        return ExprFuncBuilder(self.builder.distinct())

    def null_treatment(self, null_treatment: NullTreatment) -> ExprFuncBuilder:
        """Set how nulls are treated for either window or aggregate functions."""
        return ExprFuncBuilder(self.builder.null_treatment(null_treatment.value))

    def partition_by(self, *partition_by: Expr) -> ExprFuncBuilder:
        """Set partitioning for window functions."""
        return ExprFuncBuilder(
            self.builder.partition_by([e.expr for e in partition_by])
        )

    def window_frame(self, window_frame: WindowFrame) -> ExprFuncBuilder:
        """Set window frame for window functions."""
        return ExprFuncBuilder(self.builder.window_frame(window_frame.window_frame))

    def build(self) -> Expr:
        """Create an expression from a Function Builder."""
        return Expr(self.builder.build())


class Window:
    """Define reusable window parameters."""

    def __init__(
        self,
        partition_by: list[Expr] | Expr | None = None,
        window_frame: WindowFrame | None = None,
        order_by: list[SortExpr | Expr | str] | Expr | SortExpr | str | None = None,
        null_treatment: NullTreatment | None = None,
    ) -> None:
        """Construct a window definition.

        Args:
            partition_by: Partitions for window operation
            window_frame: Define the start and end bounds of the window frame
            order_by: Set ordering
            null_treatment: Indicate how nulls are to be treated
        """
        self._partition_by = partition_by
        self._window_frame = window_frame
        self._order_by = sort_list_to_raw_sort_list(order_by)
        self._null_treatment = null_treatment


class WindowFrame:
    """Defines a window frame for performing window operations."""

    def __init__(
        self, units: str, start_bound: Any | None, end_bound: Any | None
    ) -> None:
        """Construct a window frame using the given parameters.

        Args:
            units: Should be one of ``rows``, ``range``, or ``groups``.
            start_bound: Sets the preceding bound. Must be >= 0. If none, this
                will be set to unbounded. If unit type is ``groups``, this
                parameter must be set.
            end_bound: Sets the following bound. Must be >= 0. If none, this
                will be set to unbounded. If unit type is ``groups``, this
                parameter must be set.
        """
        if not isinstance(start_bound, pa.Scalar) and start_bound is not None:
            start_bound = pa.scalar(start_bound)
            if units in ("rows", "groups"):
                start_bound = start_bound.cast(pa.uint64())
        if not isinstance(end_bound, pa.Scalar) and end_bound is not None:
            end_bound = pa.scalar(end_bound)
            if units in ("rows", "groups"):
                end_bound = end_bound.cast(pa.uint64())
        self.window_frame = expr_internal.WindowFrame(units, start_bound, end_bound)

    def __repr__(self) -> str:
        """Print a string representation of the window frame."""
        return self.window_frame.__repr__()

    def get_frame_units(self) -> str:
        """Returns the window frame units for the bounds."""
        return self.window_frame.get_frame_units()

    def get_lower_bound(self) -> WindowFrameBound:
        """Returns starting bound."""
        return WindowFrameBound(self.window_frame.get_lower_bound())

    def get_upper_bound(self) -> WindowFrameBound:
        """Returns end bound."""
        return WindowFrameBound(self.window_frame.get_upper_bound())


class WindowFrameBound:
    """Defines a single window frame bound.

    :py:class:`WindowFrame` typically requires a start and end bound.
    """

    def __init__(self, frame_bound: expr_internal.WindowFrameBound) -> None:
        """Constructs a window frame bound."""
        self.frame_bound = frame_bound

    def get_offset(self) -> int | None:
        """Returns the offset of the window frame."""
        return self.frame_bound.get_offset()

    def is_current_row(self) -> bool:
        """Returns if the frame bound is current row."""
        return self.frame_bound.is_current_row()

    def is_following(self) -> bool:
        """Returns if the frame bound is following."""
        return self.frame_bound.is_following()

    def is_preceding(self) -> bool:
        """Returns if the frame bound is preceding."""
        return self.frame_bound.is_preceding()

    def is_unbounded(self) -> bool:
        """Returns if the frame bound is unbounded."""
        return self.frame_bound.is_unbounded()


class CaseBuilder:
    """Builder class for constructing case statements.

    Examples:
        >>> ctx = dfn.SessionContext()
        >>> df = ctx.from_pydict({"a": [1, 2, 3]})
        >>> result = df.select(
        ...     dfn.functions.case(dfn.col("a"))
        ...     .when(dfn.lit(1), dfn.lit("One"))
        ...     .when(dfn.lit(2), dfn.lit("Two"))
        ...     .otherwise(dfn.lit("Other"))
        ...     .alias("label")
        ... )
        >>> result.to_pydict()
        {'label': ['One', 'Two', 'Other']}
    """

    def __init__(self, case_builder: expr_internal.CaseBuilder) -> None:
        """Constructs a case builder.

        This is not typically called by the end user directly. See
        :py:func:`datafusion.functions.case` instead.
        """
        self.case_builder = case_builder

    def when(self, when_expr: Expr, then_expr: Expr) -> CaseBuilder:
        """Add a case to match against."""
        return CaseBuilder(self.case_builder.when(when_expr.expr, then_expr.expr))

    def otherwise(self, else_expr: Expr) -> Expr:
        """Set a default value for the case statement."""
        return Expr(self.case_builder.otherwise(else_expr.expr))

    def end(self) -> Expr:
        """Finish building a case statement.

        Any non-matching cases will end in a `null` value.
        """
        return Expr(self.case_builder.end())


class SortExpr:
    """Used to specify sorting on either a DataFrame or function."""

    def __init__(self, expr: Expr, ascending: bool, nulls_first: bool) -> None:
        """This constructor should not be called by the end user."""
        self.raw_sort = expr_internal.SortExpr(expr.expr, ascending, nulls_first)

    def expr(self) -> Expr:
        """Return the raw expr backing the SortExpr."""
        return Expr(self.raw_sort.expr())

    def ascending(self) -> bool:
        """Return ascending property."""
        return self.raw_sort.ascending()

    def nulls_first(self) -> bool:
        """Return nulls_first property."""
        return self.raw_sort.nulls_first()

    def __repr__(self) -> str:
        """Generate a string representation of this expression."""
        return self.raw_sort.__repr__()


SortKey = Expr | SortExpr | str


class GroupingSet:
    """Factory for creating grouping set expressions.

    Grouping sets control how
    :py:meth:`~datafusion.dataframe.DataFrame.aggregate` groups rows.
    Instead of a single ``GROUP BY``, they produce multiple grouping
    levels in one pass — subtotals, cross-tabulations, or arbitrary
    column subsets.

    Use :py:func:`~datafusion.functions.grouping` in the aggregate list
    to tell which columns are aggregated across in each result row.
    """

    @staticmethod
    def rollup(*exprs: Expr | str) -> Expr:
        """Create a ``ROLLUP`` grouping set for use with ``aggregate()``.

        ``ROLLUP`` generates all prefixes of the given column list as
        grouping sets. For example, ``rollup(a, b)`` produces grouping
        sets ``(a, b)``, ``(a)``, and ``()`` (grand total).

        This is equivalent to ``GROUP BY ROLLUP(a, b)`` in SQL.

        Args:
            *exprs: Column expressions or column name strings to
                include in the rollup.

        Examples:
            >>> from datafusion.expr import GroupingSet
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 1, 2], "b": [10, 20, 30]})
            >>> result = df.aggregate(
            ...     [GroupingSet.rollup(dfn.col("a"))],
            ...     [dfn.functions.sum(dfn.col("b")).alias("s"),
            ...      dfn.functions.grouping(dfn.col("a"))],
            ... ).sort(dfn.col("a").sort(nulls_first=False))
            >>> result.collect_column("s").to_pylist()
            [30, 30, 60]

        See Also:
            :py:meth:`cube`, :py:meth:`grouping_sets`,
            :py:func:`~datafusion.functions.grouping`
        """
        args = [_to_raw_expr(e) for e in exprs]
        return Expr(expr_internal.GroupingSet.rollup(*args))

    @staticmethod
    def cube(*exprs: Expr | str) -> Expr:
        """Create a ``CUBE`` grouping set for use with ``aggregate()``.

        ``CUBE`` generates all possible subsets of the given column list
        as grouping sets. For example, ``cube(a, b)`` produces grouping
        sets ``(a, b)``, ``(a)``, ``(b)``, and ``()`` (grand total).

        This is equivalent to ``GROUP BY CUBE(a, b)`` in SQL.

        Args:
            *exprs: Column expressions or column name strings to
                include in the cube.

        Examples:
            With a single column, ``cube`` behaves identically to
            :py:meth:`rollup`:

            >>> from datafusion.expr import GroupingSet
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 1, 2], "b": [10, 20, 30]})
            >>> result = df.aggregate(
            ...     [GroupingSet.cube(dfn.col("a"))],
            ...     [dfn.functions.sum(dfn.col("b")).alias("s"),
            ...      dfn.functions.grouping(dfn.col("a"))],
            ... ).sort(dfn.col("a").sort(nulls_first=False))
            >>> result.collect_column("s").to_pylist()
            [30, 30, 60]

        See Also:
            :py:meth:`rollup`, :py:meth:`grouping_sets`,
            :py:func:`~datafusion.functions.grouping`
        """
        args = [_to_raw_expr(e) for e in exprs]
        return Expr(expr_internal.GroupingSet.cube(*args))

    @staticmethod
    def grouping_sets(*expr_lists: list[Expr | str]) -> Expr:
        """Create explicit grouping sets for use with ``aggregate()``.

        Each argument is a list of column expressions or column name
        strings representing one grouping set. For example,
        ``grouping_sets([a], [b])`` groups by ``a`` alone and by ``b``
        alone in a single query.

        This is equivalent to ``GROUP BY GROUPING SETS ((a), (b))`` in
        SQL.

        Args:
            *expr_lists: Each positional argument is a list of
                expressions or column name strings forming one
                grouping set.

        Examples:
            >>> from datafusion.expr import GroupingSet
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict(
            ...     {"a": ["x", "x", "y"], "b": ["m", "n", "m"],
            ...      "c": [1, 2, 3]})
            >>> result = df.aggregate(
            ...     [GroupingSet.grouping_sets(
            ...         [dfn.col("a")], [dfn.col("b")])],
            ...     [dfn.functions.sum(dfn.col("c")).alias("s"),
            ...      dfn.functions.grouping(dfn.col("a")),
            ...      dfn.functions.grouping(dfn.col("b"))],
            ... ).sort(
            ...     dfn.col("a").sort(nulls_first=False),
            ...     dfn.col("b").sort(nulls_first=False),
            ... )
            >>> result.collect_column("s").to_pylist()
            [3, 3, 4, 2]

        See Also:
            :py:meth:`rollup`, :py:meth:`cube`,
            :py:func:`~datafusion.functions.grouping`
        """
        raw_lists = [[_to_raw_expr(e) for e in lst] for lst in expr_lists]
        return Expr(expr_internal.GroupingSet.grouping_sets(*raw_lists))
