# 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

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

if sys.version_info >= (3, 13):
    from warnings import deprecated
else:
    from typing_extensions import deprecated

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


@deprecated("CreateExternalTable.location() is deprecated; use locations() instead.")
def _create_external_table_location(self: Any) -> str:
    """Return the first external table location.

    Use :meth:`CreateExternalTable.locations` instead.

    Examples:
        >>> class Command:
        ...     def locations(self) -> list[str]:
        ...         return ["data.csv"]
        >>> Command().locations()
        ['data.csv']
    """
    locations = self.locations()
    return locations[0] if locations else ""


CreateExternalTable.location = _create_external_table_location  # ty: ignore[deprecated]

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)


@overload
def expr_list_to_raw_expr_list(expr_list: None) -> None: ...


@overload
def expr_list_to_raw_expr_list(
    expr_list: Sequence[Expr | str] | Expr | str,
) -> list[expr_internal.Expr]: ...


def expr_list_to_raw_expr_list(
    expr_list: Sequence[Expr | str] | Expr | str | 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=False).raw_sort


@overload
def sort_list_to_raw_sort_list(sort_list: None) -> None: ...


@overload
def sort_list_to_raw_sort_list(
    sort_list: Sequence[SortKey] | SortKey,
) -> list[expr_internal.SortExpr]: ...


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

        Note that the global context carries no extension codecs, so
        falling back to it cannot decode a payload written by one. A
        worker that must decode extension-codec payloads has to install a
        context carrying those codecs — see
        :func:`datafusion.ipc.set_worker_ctx` and
        :meth:`SessionContext.with_extensions`.

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

        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.

        Examples:
            >>> import pickle
            >>> from datafusion import col, lit
            >>> e = col("a") * lit(2)
            >>> pickle.loads(pickle.dumps(e)).canonical_name()
            'a * Int64(2)'
        """
        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:  # ty: ignore[invalid-method-override]
        """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:  # ty: ignore[invalid-method-override]
        """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 = False) -> 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. It raises on a window
        function unless that is an aggregate used as one. 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. It raises on a window
        function unless that is an aggregate used as one. 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. It raises on an
        aggregate function that has not been turned into a window function with
        :py:meth:`over`. 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 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. It raises on an
        aggregate function that has not been turned into a window function with
        :py:meth:`over`. 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:
        """Evaluate an aggregate or window function over a window.

        On an aggregate function this turns it into a window function. With the
        exception of ``partition_by``, how each of the parameters is used is determined
        by the underlying aggregate function.

        On an aggregate, the ``null_treatment``, ``filter``, and ``distinct`` options
        it was built with are kept, and an ``order_by`` raises; see
        :ref:`aggregate_over_options`.

        On a window function that already has a ``partition_by``, ``order_by``, or
        ``window_frame``, this raises; see :ref:`window_function_chaining`.

        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 is_nan(self) -> Expr:
        """Returns true if a given number is +NaN or -NaN otherwise returns false."""
        from . import functions as F

        return F.is_nan(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:
    """Sets the options of an aggregate or window function.

    ``filter`` and ``distinct`` apply to an aggregate, including one used as a
    window function; ``partition_by`` and ``window_frame`` apply to a window
    function. Starting a builder from a window function that already has a
    ``partition_by``, ``order_by``, or ``window_frame`` raises; see
    :ref:`window_function_chaining`.
    """

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