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


# 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 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,
        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. 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 — 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([], [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]}
        """
        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,
    ) -> 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`.

        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
        """
        fmt = format.value if format is not None else None
        self.df.explain(verbose, analyze, fmt)

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

        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]

        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
        """
        return DataFrame(self.df.fill_null(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
        )
