# 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:`DataFrame` — lazy, chainable query representation.

A :py:class:`DataFrame` is a logical plan over one or more data sources.
Methods that reshape the plan (:py:meth:`DataFrame.select`,
:py:meth:`DataFrame.filter`, :py:meth:`DataFrame.aggregate`,
:py:meth:`DataFrame.sort`, :py:meth:`DataFrame.join`,
:py:meth:`DataFrame.limit`, the set-operation methods, ...) return a new
:py:class:`DataFrame` and do no work until a terminal method such as
:py:meth:`DataFrame.collect`, :py:meth:`DataFrame.to_pydict`,
:py:meth:`DataFrame.show`, or one of the ``write_*`` methods is called.

DataFrames are produced from a
:py:class:`~datafusion.context.SessionContext`, typically via
:py:meth:`~datafusion.context.SessionContext.sql`,
:py:meth:`~datafusion.context.SessionContext.read_csv`,
:py:meth:`~datafusion.context.SessionContext.read_parquet`, or
:py:meth:`~datafusion.context.SessionContext.from_pydict`.

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

See :ref:`user_guide_concepts` in the online documentation for a high-level
overview of the execution model.
"""

from __future__ import annotations

import sys
import warnings
from collections.abc import AsyncIterator, Iterable, Iterator, Sequence
from typing import (
    TYPE_CHECKING,
    Any,
    Literal,
    cast,
    overload,
)

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

from datafusion._internal import DataFrame as DataFrameInternal
from datafusion._internal import DataFrameWriteOptions as DataFrameWriteOptionsInternal
from datafusion._internal import InsertOp as InsertOpInternal
from datafusion._internal import ParquetColumnOptions as ParquetColumnOptionsInternal
from datafusion._internal import ParquetWriterOptions as ParquetWriterOptionsInternal
from datafusion.expr import (
    Expr,
    SortExpr,
    SortKey,
    _to_raw_expr,
    ensure_expr,
    ensure_expr_list,
    expr_list_to_raw_expr_list,
    sort_list_to_raw_sort_list,
)
from datafusion.plan import ExecutionPlan, LogicalPlan
from datafusion.record_batch import RecordBatch, RecordBatchStream

if TYPE_CHECKING:
    import pathlib
    from collections.abc import Callable

    import pandas as pd
    import polars as pl
    import pyarrow as pa

    from datafusion.catalog import Table

from enum import Enum


class ExplainFormat(Enum):
    """Output format for explain plans.

    Controls how the query plan is rendered in :py:meth:`DataFrame.explain`.
    """

    INDENT = "indent"
    """Default indented text format."""

    TREE = "tree"
    """Tree-style visual format with box-drawing characters."""

    PGJSON = "pgjson"
    """PostgreSQL-compatible JSON format for use with visualization tools."""

    GRAPHVIZ = "graphviz"
    """Graphviz DOT format for graph rendering."""


class ExplainAnalyzeLevel(Enum):
    """Which metrics :py:meth:`DataFrame.explain` reports when ``analyze=True``."""

    SUMMARY = "summary"
    """Common metrics for finding which operator is slow."""

    DEV = "dev"
    """All metrics, including those for deep operator-level introspection."""


class ExplainMetricCategory(Enum):
    """Category of metric reported by :py:meth:`DataFrame.explain` with ``analyze``."""

    ROWS = "rows"
    """Row counts, such as ``output_rows``."""

    BYTES = "bytes"
    """Byte sizes, such as ``output_bytes``."""

    TIMING = "timing"
    """Elapsed times, such as ``elapsed_compute``."""

    UNCATEGORIZED = "uncategorized"
    """Metrics that declare no category."""


# excerpt from deltalake
# https://github.com/apache/datafusion-python/pull/981#discussion_r1905619163
class Compression(Enum):
    """Enum representing the available compression types for Parquet files."""

    UNCOMPRESSED = "uncompressed"
    SNAPPY = "snappy"
    GZIP = "gzip"
    BROTLI = "brotli"
    LZ4 = "lz4"
    # lzo is not implemented yet
    # https://github.com/apache/arrow-rs/issues/6970
    # LZO = "lzo"  # noqa: ERA001
    ZSTD = "zstd"
    LZ4_RAW = "lz4_raw"

    @classmethod
    def from_str(cls: type[Compression], value: str) -> Compression:
        """Convert a string to a Compression enum value.

        Args:
            value: The string representation of the compression type.

        Returns:
            The Compression enum lowercase value.

        Raises:
            ValueError: If the string does not match any Compression enum value.
        """
        try:
            return cls(value.lower())
        except ValueError as err:
            valid_values = str([item.value for item in Compression])
            error_msg = f"""
                {value} is not a valid Compression.
                Valid values are: {valid_values}
                """
            raise ValueError(error_msg) from err

    def get_default_level(self) -> int | None:
        """Get the default compression level for the compression type.

        Returns:
            The default compression level for the compression type.
        """
        # GZIP, BROTLI default values from deltalake repo
        # https://github.com/apache/datafusion-python/pull/981#discussion_r1905619163
        # ZSTD default value from delta-rs
        # https://github.com/apache/datafusion-python/pull/981#discussion_r1904789223
        if self == Compression.GZIP:
            return 6
        if self == Compression.BROTLI:
            return 1
        if self == Compression.ZSTD:
            return 4
        return None


class ParquetWriterOptions:
    """Advanced parquet writer options.

    Allows settings the writer options that apply to the entire file. Some options can
    also be set on a column by column basis, with the field ``column_specific_options``
    (see ``ParquetColumnOptions``).
    """

    def __init__(
        self,
        data_pagesize_limit: int = 1024 * 1024,
        write_batch_size: int = 1024,
        writer_version: str = "1.0",
        skip_arrow_metadata: bool = False,
        compression: str | None = "zstd(3)",
        compression_level: int | None = None,
        dictionary_enabled: bool | None = True,
        dictionary_page_size_limit: int = 1024 * 1024,
        statistics_enabled: str | None = "page",
        max_row_group_size: int = 1024 * 1024,
        created_by: str = "datafusion-python",
        column_index_truncate_length: int | None = 64,
        statistics_truncate_length: int | None = None,
        data_page_row_count_limit: int = 20_000,
        encoding: str | None = None,
        bloom_filter_on_write: bool = False,
        bloom_filter_fpp: float | None = None,
        bloom_filter_ndv: int | None = None,
        allow_single_file_parallelism: bool = True,
        maximum_parallel_row_group_writers: int = 1,
        maximum_buffered_record_batches_per_stream: int = 2,
        column_specific_options: dict[str, ParquetColumnOptions] | None = None,
    ) -> None:
        """Initialize the ParquetWriterOptions.

        Args:
            data_pagesize_limit: Sets best effort maximum size of data page in bytes.
            write_batch_size: Sets write_batch_size in bytes.
            writer_version: Sets parquet writer version. Valid values are ``1.0`` and
                ``2.0``.
            skip_arrow_metadata: Skip encoding the embedded arrow metadata in the
                KV_meta.
            compression: Compression type to use. Default is ``zstd(3)``.
                Available compression types are

                - ``uncompressed``: No compression.
                - ``snappy``: Snappy compression.
                - ``gzip(n)``: Gzip compression with level n.
                - ``brotli(n)``: Brotli compression with level n.
                - ``lz4``: LZ4 compression.
                - ``lz4_raw``: LZ4_RAW compression.
                - ``zstd(n)``: Zstandard compression with level n.
            compression_level: Compression level to set.
            dictionary_enabled: Sets if dictionary encoding is enabled. If ``None``,
                uses the default parquet writer setting.
            dictionary_page_size_limit: Sets best effort maximum dictionary page size,
                in bytes.
            statistics_enabled: Sets if statistics are enabled for any column Valid
                values are ``none``, ``chunk``, and ``page``. If ``None``, uses the
                default parquet writer setting.
            max_row_group_size: Target maximum number of rows in each row group
                (defaults to 1M rows). Writing larger row groups requires more memory
                to write, but can get better compression and be faster to read.
            created_by: Sets "created by" property.
            column_index_truncate_length: Sets column index truncate length.
            statistics_truncate_length: Sets statistics truncate length. If ``None``,
                uses the default parquet writer setting.
            data_page_row_count_limit: Sets best effort maximum number of rows in a data
                page.
            encoding: Sets default encoding for any column. Valid values are ``plain``,
                ``plain_dictionary``, ``rle``, ``bit_packed``, ``delta_binary_packed``,
                ``delta_length_byte_array``, ``delta_byte_array``, ``rle_dictionary``,
                and ``byte_stream_split``. If ``None``, uses the default parquet writer
                setting.
            bloom_filter_on_write: Write bloom filters for all columns when creating
                parquet files.
            bloom_filter_fpp: Sets bloom filter false positive probability. If ``None``,
                uses the default parquet writer setting
            bloom_filter_ndv: Sets bloom filter number of distinct values. If ``None``,
                uses the default parquet writer setting.
            allow_single_file_parallelism: Controls whether DataFusion will attempt to
                speed up writing parquet files by serializing them in parallel. Each
                column in each row group in each output file are serialized in parallel
                leveraging a maximum possible core count of
                ``n_files * n_row_groups * n_columns``.
            maximum_parallel_row_group_writers: By default parallel parquet writer is
                tuned for minimum memory usage in a streaming execution plan. You may
                see a performance benefit when writing large parquet files by increasing
                ``maximum_parallel_row_group_writers`` and
                ``maximum_buffered_record_batches_per_stream`` if your system has idle
                cores and can tolerate additional memory usage. Boosting these values is
                likely worthwhile when writing out already in-memory data, such as from
                a cached data frame.
            maximum_buffered_record_batches_per_stream: See
                ``maximum_parallel_row_group_writers``.
            column_specific_options: Overrides options for specific columns. If a column
                is not a part of this dictionary, it will use the parameters provided
                here.
        """
        self.data_pagesize_limit = data_pagesize_limit
        self.write_batch_size = write_batch_size
        self.writer_version = writer_version
        self.skip_arrow_metadata = skip_arrow_metadata
        if compression_level is not None:
            self.compression = f"{compression}({compression_level})"
        else:
            self.compression = compression
        self.dictionary_enabled = dictionary_enabled
        self.dictionary_page_size_limit = dictionary_page_size_limit
        self.statistics_enabled = statistics_enabled
        self.max_row_group_size = max_row_group_size
        self.created_by = created_by
        self.column_index_truncate_length = column_index_truncate_length
        self.statistics_truncate_length = statistics_truncate_length
        self.data_page_row_count_limit = data_page_row_count_limit
        self.encoding = encoding
        self.bloom_filter_on_write = bloom_filter_on_write
        self.bloom_filter_fpp = bloom_filter_fpp
        self.bloom_filter_ndv = bloom_filter_ndv
        self.allow_single_file_parallelism = allow_single_file_parallelism
        self.maximum_parallel_row_group_writers = maximum_parallel_row_group_writers
        self.maximum_buffered_record_batches_per_stream = (
            maximum_buffered_record_batches_per_stream
        )
        self.column_specific_options = column_specific_options


class ParquetColumnOptions:
    """Parquet options for individual columns.

    Contains the available options that can be applied for an individual Parquet column,
    replacing the global options in ``ParquetWriterOptions``.
    """

    def __init__(
        self,
        encoding: str | None = None,
        dictionary_enabled: bool | None = None,
        compression: str | None = None,
        statistics_enabled: str | None = None,
        bloom_filter_enabled: bool | None = None,
        bloom_filter_fpp: float | None = None,
        bloom_filter_ndv: int | None = None,
    ) -> None:
        """Initialize the ParquetColumnOptions.

        Args:
            encoding: Sets encoding for the column path. Valid values are: ``plain``,
                ``plain_dictionary``, ``rle``, ``bit_packed``, ``delta_binary_packed``,
                ``delta_length_byte_array``, ``delta_byte_array``, ``rle_dictionary``,
                and ``byte_stream_split``. These values are not case-sensitive. If
                ``None``, uses the default parquet options
            dictionary_enabled: Sets if dictionary encoding is enabled for the column
                path. If `None`, uses the default parquet options
            compression: Sets default parquet compression codec for the column path.
                Valid values are ``uncompressed``, ``snappy``, ``gzip(level)``, ``lzo``,
                ``brotli(level)``, ``lz4``, ``zstd(level)``, and ``lz4_raw``. These
                values are not case-sensitive. If ``None``, uses the default parquet
                options.
            statistics_enabled: Sets if statistics are enabled for the column Valid
                values are: ``none``, ``chunk``, and ``page`` These values are not case
                sensitive. If ``None``, uses the default parquet options.
            bloom_filter_enabled: Sets if bloom filter is enabled for the column path.
                If ``None``, uses the default parquet options.
            bloom_filter_fpp: Sets bloom filter false positive probability for the
                column path. If ``None``, uses the default parquet options.
            bloom_filter_ndv: Sets bloom filter number of distinct values. If ``None``,
                uses the default parquet options.
        """
        self.encoding = encoding
        self.dictionary_enabled = dictionary_enabled
        self.compression = compression
        self.statistics_enabled = statistics_enabled
        self.bloom_filter_enabled = bloom_filter_enabled
        self.bloom_filter_fpp = bloom_filter_fpp
        self.bloom_filter_ndv = bloom_filter_ndv


class DataFrame:
    """Two dimensional table representation of data.

    DataFrame objects are iterable; iterating over a DataFrame yields
    :class:`datafusion.RecordBatch` instances lazily.

    See :ref:`user_guide_concepts` in the online documentation for more information.
    """

    def __init__(self, df: DataFrameInternal) -> None:
        """This constructor is not to be used by the end user.

        See :py:class:`~datafusion.context.SessionContext` for methods to
        create a :py:class:`DataFrame`.
        """
        self.df = df

    def into_view(self, temporary: bool = False) -> Table:
        """Convert ``DataFrame`` into a :class:`~datafusion.Table`.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> df = ctx.sql("SELECT 1 AS value")
            >>> view = df.into_view()
            >>> ctx.register_table("values_view", view)
            >>> result = ctx.sql("SELECT value FROM values_view").collect()
            >>> result[0].column("value").to_pylist()
            [1]
        """
        from datafusion.catalog import Table as _Table  # noqa: PLC0415

        return _Table(self.df.into_view(temporary))

    def __getitem__(self, key: str | list[str]) -> DataFrame:
        """Return a new :py:class:`DataFrame` with the specified column or columns.

        Args:
            key: Column name or list of column names to select.

        Returns:
            DataFrame with the specified column or columns.
        """
        return DataFrame(self.df.__getitem__(key))

    def __repr__(self) -> str:
        """Return a string representation of the DataFrame.

        Returns:
            String representation of the DataFrame.
        """
        return self.df.__repr__()

    def _repr_html_(self) -> str:
        return self.df._repr_html_()

    @staticmethod
    def default_str_repr(
        batches: list[pa.RecordBatch],
        schema: pa.Schema,
        has_more: bool,
        table_uuid: str | None = None,
    ) -> str:
        """Return the default string representation of a DataFrame.

        This method is used by the default formatter and implemented in Rust for
        performance reasons.
        """
        return DataFrameInternal.default_str_repr(batches, schema, has_more, table_uuid)

    def describe(self) -> DataFrame:
        """Return the statistics for this DataFrame.

        Only summarized numeric datatypes at the moments and returns nulls
        for non-numeric datatypes.

        The output format is modeled after pandas.

        Returns:
            A summary DataFrame containing statistics.
        """
        return DataFrame(self.df.describe())

    def schema(self) -> pa.Schema:
        """Return the :py:class:`pyarrow.Schema` of this DataFrame.

        The output schema contains information on the name, data type, and
        nullability for each column.

        Returns:
            Describing schema of the DataFrame
        """
        return self.df.schema()

    def column(self, name: str) -> Expr:
        """Return a fully qualified column expression for ``name``.

        Resolves an unqualified column name against this DataFrame's schema
        and returns an :py:class:`Expr` whose underlying column reference
        includes the table qualifier. This is especially useful after joins,
        where the same column name may appear in multiple relations.

        Args:
            name: Unqualified column name to look up.

        Returns:
            A fully qualified column expression.

        Raises:
            Exception: If the column is not found or is ambiguous (exists in
                multiple relations).

        Examples:
            Resolve a column from a simple DataFrame:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2], "b": [3, 4]})
            >>> expr = df.column("a")
            >>> df.select(expr).to_pydict()
            {'a': [1, 2]}

            Resolve qualified columns after a join:

            >>> left = ctx.from_pydict({"id": [1, 2], "x": [10, 20]})
            >>> right = ctx.from_pydict({"id": [1, 2], "y": [30, 40]})
            >>> joined = left.join(right, on="id", how="inner")
            >>> expr = joined.column("y")
            >>> joined.select("id", expr).sort("id").to_pydict()
            {'id': [1, 2], 'y': [30, 40]}
        """
        return self.find_qualified_columns(name)[0]

    def col(self, name: str) -> Expr:
        """Alias for :py:meth:`column`.

        See Also:
            :py:meth:`column`
        """
        return self.column(name)

    def find_qualified_columns(self, *names: str) -> list[Expr]:
        """Return fully qualified column expressions for the given names.

        This is a batch version of :py:meth:`column` — it resolves each
        unqualified name against the DataFrame's schema and returns a list
        of qualified column expressions.

        Args:
            names: Unqualified column names to look up.

        Returns:
            List of fully qualified column expressions, one per name.

        Raises:
            Exception: If any column is not found or is ambiguous.

        Examples:
            Resolve multiple columns at once:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2], "b": [3, 4], "c": [5, 6]})
            >>> exprs = df.find_qualified_columns("a", "c")
            >>> df.select(*exprs).to_pydict()
            {'a': [1, 2], 'c': [5, 6]}
        """
        raw_exprs = self.df.find_qualified_columns(list(names))
        return [Expr(e) for e in raw_exprs]

    def select_exprs(self, *args: str) -> DataFrame:
        """Project arbitrary list of expression strings into a new DataFrame.

        This method will parse string expressions into logical plan expressions.
        The output DataFrame has one column for each expression.

        Returns:
            DataFrame only containing the specified columns.
        """
        return self.df.select_exprs(*args)

    def alias(self, alias: str) -> DataFrame:
        """Assign a table alias to this :py:class:`DataFrame`.

        Replaces the qualifiers of the output columns with ``alias``. Useful for
        self-joins and any situation that needs an unambiguous table-style
        qualifier (``alias.col``) for downstream references.

        Args:
            alias: Table alias to apply to the DataFrame's columns.

        Returns:
            DataFrame with columns re-qualified under ``alias``.

        Example:
            >>> from datafusion import col
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"id": [1, 2], "val": [10, 20]})
            >>> left = df.alias("l")
            >>> right = df.alias("r")
            >>> left.join(right, left_on="id", right_on="id").select(
            ...     "id", col("l.val").alias("lval"), col("r.val").alias("rval")
            ... ).sort("id").to_pydict()
            {'id': [1, 2], 'lval': [10, 20], 'rval': [10, 20]}
        """
        return DataFrame(self.df.alias(alias))

    def select(self, *exprs: Expr | str) -> DataFrame:
        """Project arbitrary expressions into a new :py:class:`DataFrame`.

        String arguments are treated as column names; :py:class:`~datafusion.expr.Expr`
        arguments can reshape, rename, or compute new columns.

        Args:
            exprs: Either column names or :py:class:`~datafusion.expr.Expr` to select.

        Returns:
            DataFrame after projection. It has one column for each expression.

        Examples:
            Select columns by name:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3], "b": [10, 20, 30]})
            >>> df.select("a").to_pydict()
            {'a': [1, 2, 3]}

            Mix column names, expressions, and aliases. The string ``"a"`` selects
            column ``a`` directly; ``col("a").alias("alternate_a")`` returns a
            duplicate under a new name:

            >>> df.select("a", col("b"), col("a").alias("alternate_a")).to_pydict()
            {'a': [1, 2, 3], 'b': [10, 20, 30], 'alternate_a': [1, 2, 3]}
        """
        exprs_internal = expr_list_to_raw_expr_list(exprs)
        return DataFrame(self.df.select(*exprs_internal))

    def drop(self, *columns: str) -> DataFrame:
        """Drop arbitrary amount of columns.

        Column names are case-sensitive and require double quotes to be dropped
        if the original name is not strictly lower case.

        Args:
            columns: Column names to drop from the dataframe.

        Returns:
            DataFrame with those columns removed in the projection.

        Examples:
            To drop a lower-cased column 'a'

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2], "b": [3, 4]})
            >>> df.drop("a").schema().names
            ['b']

            Or to drop an upper-cased column 'A'

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"A": [1, 2], "b": [3, 4]})
            >>> df.drop('"A"').schema().names
            ['b']
        """
        return DataFrame(self.df.drop(*columns))

    def window(self, *exprs: Expr) -> DataFrame:
        """Add window function columns to the DataFrame.

        Applies the given window function expressions and appends the results
        as new columns.

        Args:
            exprs: Window function expressions to evaluate.

        Returns:
            DataFrame with new window function columns appended.

        Examples:
            Add a row number within each group:

            >>> import datafusion.functions as f
            >>> from datafusion import col
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3], "b": ["x", "x", "y"]})
            >>> df = df.window(
            ...     f.row_number(
            ...         partition_by=[col("b")], order_by=[col("a")]
            ...     ).alias("rn")
            ... )
            >>> "rn" in df.schema().names
            True
        """
        raw = expr_list_to_raw_expr_list(exprs)
        return DataFrame(self.df.window(*raw))

    def filter(self, *predicates: Expr | str) -> DataFrame:
        """Return a DataFrame for which ``predicate`` evaluates to ``True``.

        Rows for which ``predicate`` evaluates to ``False`` or ``None`` are filtered
        out. If more than one predicate is provided, these predicates will be
        combined as a logical AND. Each ``predicate`` can be an
        :class:`~datafusion.expr.Expr` created using helper functions such as
        :func:`datafusion.col` or :func:`datafusion.lit`, or a SQL expression string
        that will be parsed against the DataFrame schema. If more complex logic is
        required, see the logical operations in :py:mod:`~datafusion.functions`.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> df.filter(col("a") > lit(1)).to_pydict()
            {'a': [2, 3]}
            >>> df.filter("a > 1").to_pydict()
            {'a': [2, 3]}

        Args:
            predicates: Predicate expression(s) or SQL strings to filter the DataFrame.

        Returns:
            DataFrame after filtering.
        """
        df = self.df
        for predicate in predicates:
            expr = (
                self.parse_sql_expr(predicate)
                if isinstance(predicate, str)
                else predicate
            )
            df = df.filter(ensure_expr(expr))
        return DataFrame(df)

    def parse_sql_expr(self, expr: str) -> Expr:
        """Creates logical expression from a SQL query text.

        The expression is created and processed against the current schema.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> expr = df.parse_sql_expr("a > 1")
            >>> df.filter(expr).to_pydict()
            {'a': [2, 3]}

        Args:
            expr: Expression string to be converted to datafusion expression

        Returns:
            Logical expression .
        """
        return Expr(self.df.parse_sql_expr(expr))

    def with_column(self, name: str, expr: Expr | str) -> DataFrame:
        """Add an additional column to the DataFrame.

        The ``expr`` must be an :class:`~datafusion.expr.Expr` constructed with
        :func:`datafusion.col` or :func:`datafusion.lit`, or a SQL expression
        string that will be parsed against the DataFrame schema.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2]})
            >>> df.with_column("b", col("a") + lit(10)).to_pydict()
            {'a': [1, 2], 'b': [11, 12]}

        Args:
            name: Name of the column to add.
            expr: Expression to compute the column.

        Returns:
            DataFrame with the new column.
        """
        expr = self.parse_sql_expr(expr) if isinstance(expr, str) else expr

        return DataFrame(self.df.with_column(name, ensure_expr(expr)))

    def with_columns(
        self, *exprs: Expr | str | Iterable[Expr | str], **named_exprs: Expr | str
    ) -> DataFrame:
        """Add columns to the DataFrame.

        By passing expressions, iterables of expressions, string SQL expressions,
        or named expressions.
        All expressions must be :class:`~datafusion.expr.Expr` objects created via
        :func:`datafusion.col` or :func:`datafusion.lit`, or SQL expression strings.
        To pass named expressions use the form ``name=Expr``.

        Example usage: The following will add 4 columns labeled ``a``, ``b``, ``c``,
        and ``d``::

            from datafusion import col, lit
            df = df.with_columns(
                col("x").alias("a"),
                [lit(1).alias("b"), col("y").alias("c")],
                d=lit(3)
            )

            Equivalent example using just SQL strings:

            df = df.with_columns(
                "x as a",
                ["1 as b", "y as c"],
                d="3"
            )

        Args:
            exprs: Either a single expression, an iterable of expressions to add or
                   SQL expression strings.
            named_exprs: Named expressions in the form of ``name=expr``

        Returns:
            DataFrame with the new columns added.
        """
        expressions = []
        for expr in exprs:
            if isinstance(expr, str):
                expressions.append(self.parse_sql_expr(expr).expr)
            elif isinstance(expr, Iterable) and not isinstance(
                expr, Expr | str | bytes | bytearray
            ):
                expressions.extend(
                    [
                        self.parse_sql_expr(e).expr
                        if isinstance(e, str)
                        else ensure_expr(e)
                        for e in expr
                    ]
                )
            else:
                expressions.append(ensure_expr(expr))

        for alias, expr in named_exprs.items():
            e = self.parse_sql_expr(expr) if isinstance(expr, str) else expr
            ensure_expr(e)
            expressions.append(e.alias(alias).expr)

        return DataFrame(self.df.with_columns(expressions))

    def with_column_renamed(self, old_name: str, new_name: str) -> DataFrame:
        r"""Rename one column by applying a new projection.

        This is a no-op if the column to be renamed does not exist.

        The method supports case sensitive rename with wrapping column name
        into one the following symbols (" or ' or \`).

        Args:
            old_name: Old column name.
            new_name: New column name.

        Returns:
            DataFrame with the column renamed.
        """
        return DataFrame(self.df.with_column_renamed(old_name, new_name))

    def aggregate(
        self,
        group_by: Sequence[Expr | str] | Expr | str | None,
        aggs: Sequence[Expr] | Expr,
    ) -> DataFrame:
        """Aggregates the rows of the current DataFrame.

        By default each unique combination of the ``group_by`` columns
        produces one row. To get multiple levels of subtotals in a
        single pass, pass a
        :py:class:`~datafusion.expr.GroupingSet` expression
        (created via
        :py:meth:`~datafusion.expr.GroupingSet.rollup`,
        :py:meth:`~datafusion.expr.GroupingSet.cube`, or
        :py:meth:`~datafusion.expr.GroupingSet.grouping_sets`)
        as the ``group_by`` argument.  See the
        :ref:`aggregation` user guide for detailed examples.

        Args:
            group_by: Sequence of expressions or column names to group
                by, or ``None`` for aggregation over the whole DataFrame.
                A :py:class:`~datafusion.expr.GroupingSet` expression may
                be included to produce multiple grouping levels (rollup,
                cube, or explicit grouping sets).
            aggs: Sequence of expressions to aggregate.

        Returns:
            DataFrame after aggregation.

        Examples:
            Aggregate without grouping — ``None`` or an empty ``group_by``
            produces a single row:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict(
            ...     {"team": ["x", "x", "y"], "score": [1, 2, 5]}
            ... )
            >>> df.aggregate(None, [F.sum(col("score")).alias("total")]).to_pydict()
            {'total': [8]}

            Group by a column and produce one row per group:

            >>> df.aggregate(
            ...     ["team"], [F.sum(col("score")).alias("total")]
            ... ).sort("team").to_pydict()
            {'team': ['x', 'y'], 'total': [3, 5]}
        """
        if group_by is None:
            group_by_list = []
        else:
            group_by_list = (
                list(group_by)
                if isinstance(group_by, Sequence)
                and not isinstance(group_by, Expr | str)
                else [group_by]
            )
        aggs_list = (
            list(aggs)
            if isinstance(aggs, Sequence) and not isinstance(aggs, Expr)
            else [aggs]
        )

        group_by_exprs = expr_list_to_raw_expr_list(group_by_list)
        aggs_exprs = ensure_expr_list(aggs_list)
        return DataFrame(self.df.aggregate(group_by_exprs, aggs_exprs))

    def sort(self, *exprs: SortKey) -> DataFrame:
        """Sort the DataFrame by the specified sorting expressions or column names.

        Note that any expression can be turned into a sort expression by
        calling its ``sort`` method. For ascending-only sorts, the shorter
        :py:meth:`sort_by` is usually more convenient.

        Args:
            exprs: Sort expressions or column names, applied in order.

        Returns:
            DataFrame after sorting.

        Examples:
            Sort ascending by a column name:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [3, 1, 2], "b": [10, 20, 30]})
            >>> df.sort("a").to_pydict()
            {'a': [1, 2, 3], 'b': [20, 30, 10]}

            Sort descending using :py:meth:`Expr.sort`:

            >>> df.sort(col("a").sort(ascending=False)).to_pydict()
            {'a': [3, 2, 1], 'b': [10, 30, 20]}
        """
        exprs_raw = sort_list_to_raw_sort_list(exprs)
        return DataFrame(self.df.sort(*exprs_raw))

    def cast(self, mapping: dict[str, pa.DataType[Any]]) -> DataFrame:
        """Cast one or more columns to a different data type.

        Args:
            mapping: Mapped with column as key and column dtype as value.

        Returns:
            DataFrame after casting columns
        """
        exprs = [Expr.column(col).cast(dtype) for col, dtype in mapping.items()]
        return self.with_columns(exprs)

    def limit(self, count: int, offset: int = 0) -> DataFrame:
        """Return a new :py:class:`DataFrame` with a limited number of rows.

        Results are returned in unspecified order unless the DataFrame is
        explicitly sorted first via :py:meth:`sort` or :py:meth:`sort_by`.

        Args:
            count: Number of rows to limit the DataFrame to.
            offset: Number of rows to skip.

        Returns:
            DataFrame after limiting.

        Examples:
            Take the first two rows:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3, 4]}).sort("a")
            >>> df.limit(2).to_pydict()
            {'a': [1, 2]}

            Skip the first row then take two (paging):

            >>> df.limit(2, offset=1).to_pydict()
            {'a': [2, 3]}
        """
        return DataFrame(self.df.limit(count, offset))

    def head(self, n: int = 5) -> DataFrame:
        """Return a new :py:class:`DataFrame` with a limited number of rows.

        Args:
            n: Number of rows to take from the head of the DataFrame.

        Returns:
            DataFrame after limiting.
        """
        return DataFrame(self.df.limit(n, 0))

    def tail(self, n: int = 5) -> DataFrame:
        """Return a new :py:class:`DataFrame` with a limited number of rows.

        Be aware this could be potentially expensive since the row size needs to be
        determined of the dataframe. This is done by collecting it.

        Args:
            n: Number of rows to take from the tail of the DataFrame.

        Returns:
            DataFrame after limiting.
        """
        return DataFrame(self.df.limit(n, max(0, self.count() - n)))

    def collect(self) -> list[pa.RecordBatch]:
        """Execute this :py:class:`DataFrame` and collect results into memory.

        Prior to calling ``collect``, modifying a DataFrame simply updates a plan
        (no actual computation is performed). Calling ``collect`` triggers the
        computation.

        Returns:
            List of :py:class:`pyarrow.RecordBatch` collected from the DataFrame.
        """
        return self.df.collect()

    def collect_column(self, column_name: str) -> pa.Array | pa.ChunkedArray:
        """Executes this :py:class:`DataFrame` for a single column."""
        return self.df.collect_column(column_name)

    def cache(self) -> DataFrame:
        """Cache the DataFrame as a memory table.

        Returns:
            Cached DataFrame.
        """
        return DataFrame(self.df.cache())

    def collect_partitioned(self) -> list[list[pa.RecordBatch]]:
        """Execute this DataFrame and collect all partitioned results.

        This operation returns :py:class:`pyarrow.RecordBatch` maintaining the input
        partitioning.

        Returns:
            List of list of :py:class:`RecordBatch` collected from the
                DataFrame.
        """
        return self.df.collect_partitioned()

    def show(self, num: int = 20) -> None:
        """Execute the DataFrame and print the result to the console.

        Args:
            num: Number of lines to show.
        """
        self.df.show(num)

    def distinct(self) -> DataFrame:
        """Return a new :py:class:`DataFrame` with all duplicated rows removed.

        Returns:
            DataFrame after removing duplicates.
        """
        return DataFrame(self.df.distinct())

    @overload
    def join(
        self,
        right: DataFrame,
        on: str | Sequence[str],
        how: Literal["inner", "left", "right", "full", "semi", "anti"] = "inner",
        *,
        left_on: None = None,
        right_on: None = None,
        join_keys: None = None,
        coalesce_duplicate_keys: bool = True,
    ) -> DataFrame: ...

    @overload
    def join(
        self,
        right: DataFrame,
        on: None = None,
        how: Literal["inner", "left", "right", "full", "semi", "anti"] = "inner",
        *,
        left_on: str | Sequence[str],
        right_on: str | Sequence[str],
        join_keys: tuple[list[str], list[str]] | None = None,
        coalesce_duplicate_keys: bool = True,
    ) -> DataFrame: ...

    @overload
    def join(
        self,
        right: DataFrame,
        on: None = None,
        how: Literal["inner", "left", "right", "full", "semi", "anti"] = "inner",
        *,
        join_keys: tuple[list[str], list[str]],
        left_on: None = None,
        right_on: None = None,
        coalesce_duplicate_keys: bool = True,
    ) -> DataFrame: ...

    def join(
        self,
        right: DataFrame,
        on: str | Sequence[str] | tuple[list[str], list[str]] | None = None,
        how: Literal["inner", "left", "right", "full", "semi", "anti"] = "inner",
        *,
        left_on: str | Sequence[str] | None = None,
        right_on: str | Sequence[str] | None = None,
        join_keys: tuple[list[str], list[str]] | None = None,
        coalesce_duplicate_keys: bool = True,
    ) -> DataFrame:
        """Join this :py:class:`DataFrame` with another :py:class:`DataFrame`.

        ``on`` has to be provided or both ``left_on`` and ``right_on`` in
        conjunction.

        When non-key columns share the same name in both DataFrames, use
        :py:meth:`DataFrame.col` on each DataFrame **before** the join to
        obtain fully qualified column references that can disambiguate them.
        See :py:meth:`join_on` for an example.

        Args:
            right: Other DataFrame to join with.
            on: Column names to join on in both dataframes.
            how: Type of join to perform. Supported types are "inner", "left",
                "right", "full", "semi", "anti".
            left_on: Join column of the left dataframe.
            right_on: Join column of the right dataframe.
            coalesce_duplicate_keys: When True, coalesce the columns
                from the right DataFrame and left DataFrame
                that have identical names in the ``on`` fields.
            join_keys: Tuple of two lists of column names to join on. [Deprecated]

        Returns:
            DataFrame after join.

        Examples:
            Inner-join two DataFrames on a shared column:

            >>> ctx = dfn.SessionContext()
            >>> left = ctx.from_pydict({"id": [1, 2, 3], "val": [10, 20, 30]})
            >>> right = ctx.from_pydict({"id": [2, 3, 4], "label": ["b", "c", "d"]})
            >>> left.join(right, on="id").sort("id").to_pydict()
            {'id': [2, 3], 'val': [20, 30], 'label': ['b', 'c']}

            Left join to keep all rows from the left side:

            >>> left.join(right, on="id", how="left").sort("id").to_pydict()
            {'id': [1, 2, 3], 'val': [10, 20, 30], 'label': [None, 'b', 'c']}

            Use ``left_on`` / ``right_on`` when the key columns differ in name:

            >>> right2 = ctx.from_pydict({"rid": [2, 3], "label": ["b", "c"]})
            >>> left.join(
            ...     right2, left_on="id", right_on="rid"
            ... ).sort("id").to_pydict()
            {'id': [2, 3], 'val': [20, 30], 'rid': [2, 3], 'label': ['b', 'c']}
        """
        if join_keys is not None:
            warnings.warn(
                "`join_keys` is deprecated, use `on` or `left_on` with `right_on`",
                category=DeprecationWarning,
                stacklevel=2,
            )
            left_on = join_keys[0]
            right_on = join_keys[1]

        # This check is to prevent breaking API changes where users prior to
        # DF 43.0.0 would  pass the join_keys as a positional argument instead
        # of a keyword argument.
        if (
            isinstance(on, tuple)
            and len(on) == 2  # noqa: PLR2004
            and isinstance(on[0], list)
            and isinstance(on[1], list)
        ):
            # We know this is safe because we've checked the types
            left_on = on[0]
            right_on = on[1]
            on = None

        if on is not None:
            if left_on is not None or right_on is not None:
                error_msg = "`left_on` or `right_on` should not provided with `on`"
                raise ValueError(error_msg)
            # The legacy ``(left, right)`` tuple form was consumed above.
            left_on = right_on = cast("str | Sequence[str]", on)
        elif left_on is not None or right_on is not None:
            if left_on is None or right_on is None:
                error_msg = "`left_on` and `right_on` should both be provided."
                raise ValueError(error_msg)
        else:
            error_msg = "either `on` or `left_on` and `right_on` should be provided."
            raise ValueError(error_msg)
        if isinstance(left_on, str):
            left_on = [left_on]
        if isinstance(right_on, str):
            right_on = [right_on]

        return DataFrame(
            self.df.join(right.df, how, left_on, right_on, coalesce_duplicate_keys)
        )

    def join_on(
        self,
        right: DataFrame,
        *on_exprs: Expr,
        how: Literal["inner", "left", "right", "full", "semi", "anti"] = "inner",
    ) -> DataFrame:
        """Join two :py:class:`DataFrame` using the specified expressions.

        Join predicates must be :class:`~datafusion.expr.Expr` objects, typically
        built with :func:`datafusion.col`. On expressions are used to support
        in-equality predicates. Equality predicates are correctly optimized.

        Use :py:meth:`DataFrame.col` on each DataFrame **before** the join to
        obtain fully qualified column references. These qualified references
        can then be used in the join predicate and to disambiguate columns
        with the same name when selecting from the result.

        Examples:
            Join with unique column names:

            >>> ctx = dfn.SessionContext()
            >>> left = ctx.from_pydict({"a": [1, 2], "x": ["a", "b"]})
            >>> right = ctx.from_pydict({"b": [1, 2], "y": ["c", "d"]})
            >>> left.join_on(
            ...     right, col("a") == col("b")
            ... ).sort(col("x")).to_pydict()
            {'a': [1, 2], 'x': ['a', 'b'], 'b': [1, 2], 'y': ['c', 'd']}

            Use :py:meth:`col` to disambiguate shared column names:

            >>> left = ctx.from_pydict({"id": [1, 2], "val": [10, 20]})
            >>> right = ctx.from_pydict({"id": [1, 2], "val": [30, 40]})
            >>> joined = left.join_on(
            ...     right, left.col("id") == right.col("id"), how="inner"
            ... )
            >>> joined.select(
            ...     left.col("id"), left.col("val"), right.col("val").alias("rval")
            ... ).sort(left.col("id")).to_pydict()
            {'id': [1, 2], 'val': [10, 20], 'rval': [30, 40]}

        Args:
            right: Other DataFrame to join with.
            on_exprs: single or multiple (in)-equality predicates.
            how: Type of join to perform. Supported types are "inner", "left",
                "right", "full", "semi", "anti".

        Returns:
            DataFrame after join.
        """
        exprs = [ensure_expr(expr) for expr in on_exprs]
        return DataFrame(self.df.join_on(right.df, exprs, how))

    def explain(
        self,
        verbose: bool = False,
        analyze: bool = False,
        format: ExplainFormat | None = None,
        show_statistics: bool | None = None,
        analyze_level: ExplainAnalyzeLevel | None = None,
        analyze_categories: Iterable[ExplainMetricCategory] | None = None,
    ) -> None:
        """Print an explanation of the DataFrame's plan so far.

        If ``analyze`` is specified, runs the plan and reports metrics.

        Args:
            verbose: If ``True``, more details will be included.
            analyze: If ``True``, the plan will run and metrics reported.
            format: Output format for the plan. Defaults to
                :py:attr:`ExplainFormat.INDENT`.
            show_statistics: If ``True``, include each operator's statistics.
                ``None`` uses the ``datafusion.explain.show_statistics``
                setting.
            analyze_level: Which metrics to report with ``analyze``. ``None``
                uses the ``datafusion.explain.analyze_level`` setting.
            analyze_categories: Report only metrics in these categories with
                ``analyze``; an empty iterable reports none. ``None`` uses the
                ``datafusion.explain.analyze_categories`` setting.

        Raises:
            ValueError: If ``show_statistics`` is set with ``analyze``, or
                ``analyze_level`` or ``analyze_categories`` is set without it.

        Examples:
            Show the plan in tree format:

            >>> from datafusion import ExplainFormat
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> df.explain(format=ExplainFormat.TREE)  # doctest: +SKIP

            Show plan with runtime metrics:

            >>> df.explain(analyze=True)  # doctest: +SKIP

            Show only row-count metrics:

            >>> from datafusion.dataframe import ExplainMetricCategory
            >>> df.explain(
            ...     analyze=True, analyze_categories=[ExplainMetricCategory.ROWS]
            ... )  # doctest: +SKIP
        """
        if analyze and show_statistics is not None:
            msg = "show_statistics cannot be combined with analyze"
            raise ValueError(msg)
        if not analyze and analyze_level is not None:
            msg = "analyze_level requires analyze"
            raise ValueError(msg)
        if not analyze and analyze_categories is not None:
            msg = "analyze_categories requires analyze"
            raise ValueError(msg)
        fmt = format.value if format is not None else None
        level = analyze_level.value if analyze_level is not None else None
        categories = (
            [c.value for c in analyze_categories]
            if analyze_categories is not None
            else None
        )
        self.df.explain(verbose, analyze, fmt, show_statistics, level, categories)

    def logical_plan(self) -> LogicalPlan:
        """Return the unoptimized ``LogicalPlan``.

        Returns:
            Unoptimized logical plan.
        """
        return LogicalPlan(self.df.logical_plan())

    def optimized_logical_plan(self) -> LogicalPlan:
        """Return the optimized ``LogicalPlan``.

        Returns:
            Optimized logical plan.
        """
        return LogicalPlan(self.df.optimized_logical_plan())

    def execution_plan(self) -> ExecutionPlan:
        """Return the execution/physical plan.

        Returns:
            Execution plan.
        """
        return ExecutionPlan(self.df.execution_plan())

    def repartition(self, num: int) -> DataFrame:
        """Repartition a DataFrame into ``num`` partitions.

        The batches allocation uses a round-robin algorithm.

        Args:
            num: Number of partitions to repartition the DataFrame into.

        Returns:
            Repartitioned DataFrame.
        """
        return DataFrame(self.df.repartition(num))

    def repartition_by_hash(self, *exprs: Expr | str, num: int) -> DataFrame:
        """Repartition a DataFrame using a hash partitioning scheme.

        Args:
            exprs: Expressions or a SQL expression string to evaluate
                   and perform hashing on.
            num: Number of partitions to repartition the DataFrame into.

        Returns:
            Repartitioned DataFrame.
        """
        raw_exprs = expr_list_to_raw_expr_list(
            [self.parse_sql_expr(e) if isinstance(e, str) else e for e in exprs]
        )

        return DataFrame(self.df.repartition_by_hash(*raw_exprs, num=num))

    def union(self, other: DataFrame, distinct: bool = False) -> DataFrame:
        """Calculate the union of two :py:class:`DataFrame`.

        The two :py:class:`DataFrame` must have exactly the same schema.

        Args:
            other: DataFrame to union with.
            distinct: If ``True``, duplicate rows will be removed.

        Returns:
            DataFrame after union.

        Examples:
            Stack rows from both DataFrames, preserving duplicates:

            >>> ctx = dfn.SessionContext()
            >>> df1 = ctx.from_pydict({"a": [1, 2]})
            >>> df2 = ctx.from_pydict({"a": [2, 3]})
            >>> df1.union(df2).sort("a").to_pydict()
            {'a': [1, 2, 2, 3]}

            Deduplicate the combined result with ``distinct=True``:

            >>> df1.union(df2, distinct=True).sort("a").to_pydict()
            {'a': [1, 2, 3]}
        """
        return DataFrame(self.df.union(other.df, distinct))

    @deprecated(
        "union_distinct() is deprecated. Use union(other, distinct=True) instead."
    )
    def union_distinct(self, other: DataFrame) -> DataFrame:
        """Calculate the distinct union of two :py:class:`DataFrame`.

        See Also:
            :py:meth:`union`
        """
        return self.union(other, distinct=True)

    def intersect(self, other: DataFrame, distinct: bool = False) -> DataFrame:
        """Calculate the intersection of two :py:class:`DataFrame`.

        The two :py:class:`DataFrame` must have exactly the same schema.

        Args:
            other: DataFrame to intersect with.
            distinct: If ``True``, duplicate rows are removed from the result.

        Returns:
            DataFrame after intersection.

        Examples:
            Find rows common to both DataFrames:

            >>> ctx = dfn.SessionContext()
            >>> df1 = ctx.from_pydict({"a": [1, 2, 3], "b": [10, 20, 30]})
            >>> df2 = ctx.from_pydict({"a": [1, 4], "b": [10, 40]})
            >>> df1.intersect(df2).to_pydict()
            {'a': [1], 'b': [10]}

            Intersect with deduplication:

            >>> df1 = ctx.from_pydict({"a": [1, 1, 2], "b": [10, 10, 20]})
            >>> df2 = ctx.from_pydict({"a": [1, 1], "b": [10, 10]})
            >>> df1.intersect(df2, distinct=True).to_pydict()
            {'a': [1], 'b': [10]}
        """
        return DataFrame(self.df.intersect(other.df, distinct))

    def except_all(self, other: DataFrame, distinct: bool = False) -> DataFrame:
        """Calculate the set difference of two :py:class:`DataFrame`.

        Returns rows that are in this DataFrame but not in ``other``.

        The two :py:class:`DataFrame` must have exactly the same schema.

        Args:
            other: DataFrame to calculate exception with.
            distinct: If ``True``, duplicate rows are removed from the result.

        Returns:
            DataFrame after set difference.

        Examples:
            Remove rows present in ``df2``:

            >>> ctx = dfn.SessionContext()
            >>> df1 = ctx.from_pydict({"a": [1, 2, 3], "b": [10, 20, 30]})
            >>> df2 = ctx.from_pydict({"a": [1, 2], "b": [10, 20]})
            >>> df1.except_all(df2).sort("a").to_pydict()
            {'a': [3], 'b': [30]}

            Remove rows present in ``df2`` and deduplicate:

            >>> df1.except_all(df2, distinct=True).sort("a").to_pydict()
            {'a': [3], 'b': [30]}
        """
        return DataFrame(self.df.except_all(other.df, distinct))

    def union_by_name(self, other: DataFrame, distinct: bool = False) -> DataFrame:
        """Union two :py:class:`DataFrame` matching columns by name.

        Unlike :py:meth:`union` which matches columns by position, this method
        matches columns by their names, allowing DataFrames with different
        column orders to be combined.

        Args:
            other: DataFrame to union with.
            distinct: If ``True``, duplicate rows are removed from the result.

        Returns:
            DataFrame after union by name.

        Examples:
            Combine DataFrames with different column orders:

            >>> ctx = dfn.SessionContext()
            >>> df1 = ctx.from_pydict({"a": [1], "b": [10]})
            >>> df2 = ctx.from_pydict({"b": [20], "a": [2]})
            >>> df1.union_by_name(df2).sort("a").to_pydict()
            {'a': [1, 2], 'b': [10, 20]}

            Union by name with deduplication:

            >>> df1 = ctx.from_pydict({"a": [1, 1], "b": [10, 10]})
            >>> df2 = ctx.from_pydict({"b": [10], "a": [1]})
            >>> df1.union_by_name(df2, distinct=True).to_pydict()
            {'a': [1], 'b': [10]}
        """
        return DataFrame(self.df.union_by_name(other.df, distinct))

    def distinct_on(
        self,
        on_expr: list[Expr],
        select_expr: list[Expr],
        sort_expr: list[SortKey] | None = None,
    ) -> DataFrame:
        """Deduplicate rows based on specific columns.

        Returns a new DataFrame with one row per unique combination of the
        ``on_expr`` columns, keeping the first row per group as determined by
        ``sort_expr``.

        Args:
            on_expr: Expressions that determine uniqueness.
            select_expr: Expressions to include in the output.
            sort_expr: Optional sort expressions to determine which row to keep.

        Returns:
            DataFrame after deduplication.

        Examples:
            Keep the row with the smallest ``b`` for each unique ``a``:

            >>> from datafusion import col
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 1, 2, 2], "b": [10, 20, 30, 40]})
            >>> df.distinct_on(
            ...     [col("a")],
            ...     [col("a"), col("b")],
            ...     [col("a").sort(ascending=True), col("b").sort(ascending=True)],
            ... ).sort("a").to_pydict()
            {'a': [1, 2], 'b': [10, 30]}
        """
        on_raw = expr_list_to_raw_expr_list(on_expr)
        select_raw = expr_list_to_raw_expr_list(select_expr)
        sort_raw = sort_list_to_raw_sort_list(sort_expr) if sort_expr else None
        return DataFrame(self.df.distinct_on(on_raw, select_raw, sort_raw))

    def sort_by(self, *exprs: Expr | str) -> DataFrame:
        """Sort the DataFrame by column expressions in ascending order.

        This is a convenience method that sorts the DataFrame by the given
        expressions in ascending order with nulls last. For more control over
        sort direction and null ordering, use :py:meth:`sort` instead.

        Args:
            exprs: Expressions or column names to sort by.

        Returns:
            DataFrame after sorting.

        Examples:
            Sort by a single column:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [3, 1, 2]})
            >>> df.sort_by("a").to_pydict()
            {'a': [1, 2, 3]}
        """
        raw = [_to_raw_expr(e) for e in exprs]
        return DataFrame(self.df.sort_by(raw))

    def write_csv(
        self,
        path: str | pathlib.Path,
        with_header: bool = False,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None:
        """Execute the :py:class:`DataFrame`  and write the results to a CSV file.

        Args:
            path: Path of the CSV file to write.
            with_header: If true, output the CSV header row.
            write_options: Options that impact how the DataFrame is written.
        """
        raw_write_options = (
            write_options._raw_write_options if write_options is not None else None
        )
        self.df.write_csv(str(path), with_header, raw_write_options)

    @overload
    def write_parquet(
        self,
        path: str | pathlib.Path,
        compression: str,
        compression_level: int | None = None,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None: ...

    @overload
    def write_parquet(
        self,
        path: str | pathlib.Path,
        compression: Compression = Compression.ZSTD,
        compression_level: int | None = None,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None: ...

    @overload
    def write_parquet(
        self,
        path: str | pathlib.Path,
        compression: ParquetWriterOptions,
        compression_level: None = None,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None: ...

    def write_parquet(
        self,
        path: str | pathlib.Path,
        compression: str | Compression | ParquetWriterOptions = Compression.ZSTD,
        compression_level: int | None = None,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None:
        """Execute the :py:class:`DataFrame` and write the results to a Parquet file.

        Available compression types are:

        - "uncompressed": No compression.
        - "snappy": Snappy compression.
        - "gzip": Gzip compression.
        - "brotli": Brotli compression.
        - "lz4": LZ4 compression.
        - "lz4_raw": LZ4_RAW compression.
        - "zstd": Zstandard compression.

        LZO compression is not yet implemented in arrow-rs and is therefore
        excluded.

        Args:
            path: Path of the Parquet file to write.
            compression: Compression type to use. Default is "ZSTD".
            compression_level: Compression level to use. For ZSTD, the
                recommended range is 1 to 22, with the default being 4. Higher levels
                provide better compression but slower speed.
            write_options: Options that impact how the DataFrame is written.
        """
        if isinstance(compression, ParquetWriterOptions):
            if compression_level is not None:
                msg = "compression_level should be None when using ParquetWriterOptions"
                raise ValueError(msg)
            self.write_parquet_with_options(path, compression, write_options)
            return

        if isinstance(compression, str):
            compression = Compression.from_str(compression)

        if (
            compression in {Compression.GZIP, Compression.BROTLI, Compression.ZSTD}
            and compression_level is None
        ):
            compression_level = compression.get_default_level()

        raw_write_options = (
            write_options._raw_write_options if write_options is not None else None
        )
        self.df.write_parquet(
            str(path),
            compression.value,
            compression_level,
            raw_write_options,
        )

    def write_parquet_with_options(
        self,
        path: str | pathlib.Path,
        options: ParquetWriterOptions,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None:
        """Execute the :py:class:`DataFrame` and write the results to a Parquet file.

        Allows advanced writer options to be set with `ParquetWriterOptions`.

        Args:
            path: Path of the Parquet file to write.
            options: Sets the writer parquet options (see `ParquetWriterOptions`).
            write_options: Options that impact how the DataFrame is written.
        """
        options_internal = ParquetWriterOptionsInternal(
            options.data_pagesize_limit,
            options.write_batch_size,
            options.writer_version,
            options.skip_arrow_metadata,
            options.compression,
            options.dictionary_enabled,
            options.dictionary_page_size_limit,
            options.statistics_enabled,
            options.max_row_group_size,
            options.created_by,
            options.column_index_truncate_length,
            options.statistics_truncate_length,
            options.data_page_row_count_limit,
            options.encoding,
            options.bloom_filter_on_write,
            options.bloom_filter_fpp,
            options.bloom_filter_ndv,
            options.allow_single_file_parallelism,
            options.maximum_parallel_row_group_writers,
            options.maximum_buffered_record_batches_per_stream,
        )

        column_specific_options_internal = {}
        for column, opts in (options.column_specific_options or {}).items():
            column_specific_options_internal[column] = ParquetColumnOptionsInternal(
                bloom_filter_enabled=opts.bloom_filter_enabled,
                encoding=opts.encoding,
                dictionary_enabled=opts.dictionary_enabled,
                compression=opts.compression,
                statistics_enabled=opts.statistics_enabled,
                bloom_filter_fpp=opts.bloom_filter_fpp,
                bloom_filter_ndv=opts.bloom_filter_ndv,
            )

        raw_write_options = (
            write_options._raw_write_options if write_options is not None else None
        )
        self.df.write_parquet_with_options(
            str(path),
            options_internal,
            column_specific_options_internal,
            raw_write_options,
        )

    def write_json(
        self,
        path: str | pathlib.Path,
        write_options: DataFrameWriteOptions | None = None,
    ) -> None:
        """Execute the :py:class:`DataFrame` and write the results to a JSON file.

        Args:
            path: Path of the JSON file to write.
            write_options: Options that impact how the DataFrame is written.
        """
        raw_write_options = (
            write_options._raw_write_options if write_options is not None else None
        )
        self.df.write_json(str(path), write_options=raw_write_options)

    def write_table(
        self, table_name: str, write_options: DataFrameWriteOptions | None = None
    ) -> None:
        """Execute the :py:class:`DataFrame` and write the results to a table.

        The table must be registered with the session to perform this operation.
        Not all table providers support writing operations. See the individual
        implementations for details.
        """
        raw_write_options = (
            write_options._raw_write_options if write_options is not None else None
        )
        self.df.write_table(table_name, raw_write_options)

    def to_arrow_table(self) -> pa.Table:
        """Execute the :py:class:`DataFrame` and convert it into an Arrow Table.

        Returns:
            Arrow Table.
        """
        return self.df.to_arrow_table()

    def execute_stream(self) -> RecordBatchStream:
        """Executes this DataFrame and returns a stream over a single partition.

        Returns:
            Record Batch Stream over a single partition.
        """
        return RecordBatchStream(self.df.execute_stream())

    def execute_stream_partitioned(self) -> list[RecordBatchStream]:
        """Executes this DataFrame and returns a stream for each partition.

        Returns:
            One record batch stream per partition.
        """
        streams = self.df.execute_stream_partitioned()
        return [RecordBatchStream(rbs) for rbs in streams]

    def to_pandas(self) -> pd.DataFrame:
        """Execute the :py:class:`DataFrame` and convert it into a Pandas DataFrame.

        Returns:
            Pandas DataFrame.
        """
        return self.df.to_pandas()

    def to_pylist(self) -> list[dict[str, Any]]:
        """Execute the :py:class:`DataFrame` and convert it into a list of dictionaries.

        Returns:
            List of dictionaries.
        """
        return self.df.to_pylist()

    def to_pydict(self) -> dict[str, list[Any]]:
        """Execute the :py:class:`DataFrame` and convert it into a dictionary of lists.

        Returns:
            Dictionary of lists.
        """
        return self.df.to_pydict()

    def to_polars(self) -> pl.DataFrame:
        """Execute the :py:class:`DataFrame` and convert it into a Polars DataFrame.

        Returns:
            Polars DataFrame.
        """
        return self.df.to_polars()

    def count(self) -> int:
        """Return the total number of rows in this :py:class:`DataFrame`.

        Note that this method will actually run a plan to calculate the
        count, which may be slow for large or complicated DataFrames.

        Returns:
            Number of rows in the DataFrame.
        """
        return self.df.count()

    def unnest_columns(
        self,
        *columns: str,
        preserve_nulls: bool = True,
        recursions: list[tuple[str, str, int]] | None = None,
    ) -> DataFrame:
        """Expand columns of arrays into a single row per array element.

        Args:
            columns: Column names to perform unnest operation on.
            preserve_nulls: If False, rows with null entries will not be
                returned.
            recursions: Optional list of ``(input_column, output_column, depth)``
                tuples that control how deeply nested columns are unnested. Any
                column not mentioned here is unnested with depth 1.

        Returns:
            A DataFrame with the columns expanded.

        Examples:
            Unnest an array column:

            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [[1, 2], [3]], "b": ["x", "y"]})
            >>> df.unnest_columns("a").to_pydict()
            {'a': [1, 2, 3], 'b': ['x', 'x', 'y']}

            With explicit recursion depth:

            >>> df.unnest_columns("a", recursions=[("a", "a", 1)]).to_pydict()
            {'a': [1, 2, 3], 'b': ['x', 'x', 'y']}
        """
        return DataFrame(
            self.df.unnest_columns(
                list(columns), preserve_nulls=preserve_nulls, recursions=recursions
            )
        )

    def __arrow_c_stream__(self, requested_schema: object | None = None) -> object:
        """Export the DataFrame as an Arrow C Stream.

        The DataFrame is executed using DataFusion's streaming APIs and exposed via
        Arrow's C Stream interface. Record batches are produced incrementally, so the
        full result set is never materialized in memory.

        When ``requested_schema`` is provided, DataFusion applies only simple
        projections such as selecting a subset of existing columns or reordering
        them. Column renaming, computed expressions, or type coercion are not
        supported through this interface.

        Args:
            requested_schema: Either a :py:class:`pyarrow.Schema` or an Arrow C
                Schema capsule (``PyCapsule``) produced by
                ``schema._export_to_c_capsule()``. The DataFrame will attempt to
                align its output with the fields and order specified by this schema.

        Returns:
            Arrow ``PyCapsule`` object representing an ``ArrowArrayStream``.

        For practical usage patterns, see the Apache Arrow streaming
        documentation: https://arrow.apache.org/docs/python/ipc.html#streaming.

        For details on DataFusion's Arrow integration and DataFrame streaming,
        see the user guide (user-guide/io/arrow and user-guide/dataframe/index).

        Notes:
            The Arrow C Data Interface PyCapsule details are documented by Apache
            Arrow and can be found at:
            https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
        """
        # ``DataFrame.__arrow_c_stream__`` in the Rust extension leverages
        # ``execute_stream_partitioned`` under the hood to stream batches while
        # preserving the original partition order.
        return self.df.__arrow_c_stream__(requested_schema)

    def __iter__(self) -> Iterator[RecordBatch]:
        """Return an iterator over this DataFrame's record batches."""
        return iter(self.execute_stream())

    def __aiter__(self) -> AsyncIterator[RecordBatch]:
        """Return an async iterator over this DataFrame's record batches.

        We're using __aiter__ because we support Python < 3.10 where aiter() is not
        available.
        """
        return self.execute_stream().__aiter__()

    def transform(self, func: Callable[..., DataFrame], *args: Any) -> DataFrame:
        """Apply a function to the current DataFrame which returns another DataFrame.

        This is useful for chaining together multiple functions.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> def add_3(df):
            ...     return df.with_column("modified", dfn.lit(3))
            >>> def within_limit(df: DataFrame, limit: int) -> DataFrame:
            ...     return df.filter(col("a") < lit(limit)).distinct()
            >>> df.transform(add_3).transform(within_limit, 4).sort("a").to_pydict()
            {'a': [1, 2, 3], 'modified': [3, 3, 3]}

        Args:
            func: A callable function that takes a DataFrame as it's first argument
            args: Zero or more arguments to pass to `func`

        Returns:
            DataFrame: After applying func to the original dataframe.
        """
        return func(self, *args)

    def fill_null(self, value: Any, subset: list[str] | None = None) -> DataFrame:
        """Fill null values in specified columns with a value.

        Args:
            value: Value to replace nulls with. Will be cast to match column type.
            subset: Optional list of column names to fill. If None, fills all columns;
                an empty list fills none.

        Returns:
            DataFrame with null values replaced where type casting is possible

        Examples:
            >>> from datafusion import SessionContext, col
            >>> ctx = SessionContext()
            >>> df = ctx.from_pydict({"a": [1, None, 3], "b": [None, 5, 6]})
            >>> filled = df.fill_null(0)
            >>> filled.sort(col("a")).collect()[0].column("a").to_pylist()
            [0, 1, 3]

            >>> df.fill_null(0, subset=[]).to_pydict()
            {'a': [1, None, 3], 'b': [None, 5, 6]}

        Notes:
            - Only fills nulls in columns where the value can be cast to the column type
            - For columns where casting fails, the original column is kept unchanged
            - For columns not in subset, the original column is kept unchanged
            - Fails on a DataFrame with an uppercase or dotted column name; see
              :ref:`fill_column_names`
        """
        if subset is not None and len(subset) == 0:
            return self
        return DataFrame(self.df.fill_null(value, subset))

    def fill_nan(self, value: float, subset: list[str] | None = None) -> DataFrame:
        """Fill NaN values in floating-point columns with a value.

        Only floating-point columns are changed; others are kept unchanged, as is
        any column ``value`` cannot be cast to. NaN is distinct from null, which
        :py:meth:`fill_null` handles. Fails on a DataFrame with an uppercase or
        dotted column name; see :ref:`fill_column_names`.

        Args:
            value: Value to replace NaN with. Will be cast to match column type.
            subset: Optional list of column names to fill. If None, fills all
                floating-point columns; an empty list fills none.

        Returns:
            DataFrame with NaN values replaced.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> nan = float("nan")
            >>> df = ctx.from_pydict({"a": [1.0, nan, None], "b": [nan, 2.0, 3.0]})
            >>> df.fill_nan(0.0).to_pydict()
            {'a': [1.0, 0.0, None], 'b': [0.0, 2.0, 3.0]}

            >>> df.fill_nan(0.0, subset=["a"]).collect_column("b")[0].as_py()
            nan

            >>> df.fill_nan(0.0, subset=[]).collect_column("b")[0].as_py()
            nan
        """
        if subset is not None and len(subset) == 0:
            return self
        return DataFrame(self.df.fill_nan(value, subset))


class InsertOp(Enum):
    """Insert operation mode.

    These modes are used by the table writing feature to define how record
    batches should be written to a table.
    """

    APPEND = InsertOpInternal.APPEND
    """Appends new rows to the existing table without modifying any existing rows."""

    REPLACE = InsertOpInternal.REPLACE
    """Replace existing rows that collide with the inserted rows.

    Replacement is typically based on a unique key or primary key.
    """

    OVERWRITE = InsertOpInternal.OVERWRITE
    """Overwrites all existing rows in the table with the new rows."""


class DataFrameWriteOptions:
    """Writer options for DataFrame.

    There is no guarantee the table provider supports all writer options.
    See the individual implementation and documentation for details.
    """

    def __init__(
        self,
        insert_operation: InsertOp | None = None,
        single_file_output: bool = False,
        partition_by: str | Sequence[str] | None = None,
        sort_by: Expr | SortExpr | Sequence[Expr] | Sequence[SortExpr] | None = None,
    ) -> None:
        """Instantiate writer options for DataFrame."""
        if isinstance(partition_by, str):
            partition_by = [partition_by]

        sort_by_raw = sort_list_to_raw_sort_list(sort_by)
        insert_op = insert_operation.value if insert_operation is not None else None

        self._raw_write_options = DataFrameWriteOptionsInternal(
            insert_op, single_file_output, partition_by, sort_by_raw
        )
