# 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_list",
    "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 coerce_to_expr_list(values: Iterable[Any]) -> list[Expr]:
    """Coerce each item in an iterable to ``Expr`` via :func:`coerce_to_expr`.

    Args:
        values: Iterable of ``Expr`` instances or Python literals to wrap.

    Returns:
        A list of ``Expr`` instances.
    """
    return [coerce_to_expr(value) for value in values]


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))
