# 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 warnings
from collections.abc import AsyncIterator, Iterable, Iterator, Sequence
from typing import (
    TYPE_CHECKING,
    Any,
    Literal,
    overload,
)

try:
    from warnings import deprecated  # Python 3.13+
except ImportError:
    from typing_extensions import deprecated  # Python 3.12

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)
            left_on = on
            right_on = 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.
        """
        exprs = [self.parse_sql_expr(e) if isinstance(e, str) else e for e in exprs]
        exprs = expr_list_to_raw_expr_list(exprs)

        return DataFrame(self.df.repartition_by_hash(*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']}
        """
        columns = list(columns)
        return DataFrame(
            self.df.unnest_columns(
                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
        )
