# 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:`SessionContext` — entry point for running DataFusion queries.

A :py:class:`SessionContext` holds registered tables, catalogs, and
configuration for the current session. It is the first object most programs
create: from it you register data, run SQL strings
(:py:meth:`SessionContext.sql`), read files
(:py:meth:`SessionContext.read_csv`,
:py:meth:`SessionContext.read_parquet`, ...), and construct
:py:class:`~datafusion.dataframe.DataFrame` objects in memory
(:py:meth:`SessionContext.from_pydict`,
:py:meth:`SessionContext.from_arrow`).

Session behavior (memory limits, batch size, configured optimizer passes,
...) is controlled by :py:class:`SessionConfig` and
:py:class:`RuntimeEnvBuilder`; SQL dialect limits are controlled by
:py:class:`SQLOptions`.

Examples:
    >>> ctx = dfn.SessionContext()
    >>> df = ctx.from_pydict({"a": [1, 2, 3]})
    >>> ctx.sql("SELECT 1 AS n").to_pydict()
    {'n': [1]}

See :ref:`user_guide_concepts` in the online documentation for the broader
execution model.
"""

from __future__ import annotations

import uuid
import warnings
from typing import TYPE_CHECKING, Any, NamedTuple, Protocol

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


from urllib.parse import urlparse

import pyarrow as pa

from datafusion.catalog import (
    Catalog,
    CatalogList,
    CatalogProviderExportable,
    CatalogProviderList,
    CatalogProviderListExportable,
    TableProviderFactory,
    TableProviderFactoryExportable,
)
from datafusion.dataframe import DataFrame
from datafusion.expr import sort_list_to_raw_sort_list
from datafusion.extensions import (
    PhysicalOptimizerRuleExportable,
    QueryPlannerExportable,
    SessionComponentsExportable,
    SessionExtensionComponents,
    SessionPlannerExportable,
)
from datafusion.options import (
    DEFAULT_MAX_INFER_SCHEMA,
    CsvReadOptions,
    _convert_table_partition_cols,
)
from datafusion.record_batch import RecordBatchStream

from ._internal import RuntimeEnvBuilder as RuntimeEnvBuilderInternal
from ._internal import SessionConfig as SessionConfigInternal
from ._internal import SessionContext as SessionContextInternal
from ._internal import SQLOptions as SQLOptionsInternal
from ._internal import expr as expr_internal

if TYPE_CHECKING:
    import pathlib
    from collections.abc import Iterable, Sequence

    import pandas as pd
    import polars as pl  # type: ignore[import]
    from _typeshed import CapsuleType as _PyCapsule

    from datafusion.catalog import CatalogProvider, Table
    from datafusion.common import DFSchema
    from datafusion.expr import Expr, SortKey
    from datafusion.plan import ExecutionPlan, LogicalPlan
    from datafusion.user_defined import (
        AggregateUDF,
        LogicalExtensionCodecExportable,
        PhysicalExtensionCodecExportable,
        ScalarUDF,
        TableFunction,
        WindowUDF,
    )


class ArrowStreamExportable(Protocol):
    """Type hint for object exporting Arrow C Stream via Arrow PyCapsule Interface.

    https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
    """

    def __arrow_c_stream__(  # noqa: D105
        self, requested_schema: object | None = None
    ) -> object: ...


class ArrowArrayExportable(Protocol):
    """Type hint for object exporting Arrow C Array via Arrow PyCapsule Interface.

    https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
    """

    def __arrow_c_array__(  # noqa: D105
        self, requested_schema: object | None = None
    ) -> tuple[object, object]: ...


class TableProviderExportable(Protocol):
    """Type hint for object that has __datafusion_table_provider__ PyCapsule.

    See :ref:`io_custom_table_provider` for registering one, and
    :ref:`extension_providers` for writing one.

    Args:
        session: See
            :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`.
            For this getter it is a session when the provider is registered
            through :py:meth:`SessionContext.register_table` and the host's
            logical codec when it goes through
            :py:meth:`datafusion.catalog.Schema.register_table`, so
            duck-typing it is not optional.
    """

    def __datafusion_table_provider__(self, session: Any) -> object: ...  # noqa: D105


class _FunctionKind(NamedTuple):
    """How one kind of declared function is resolved.

    One row per function field on
    :py:class:`~datafusion.extensions.SessionExtensionComponents`, so adding a
    kind is adding a row rather than editing three places. The dataclass
    metadata says which fields are collections to normalize; this table says
    which of them are functions and how to wrap one. Committing is not here:
    each kind is its own ``_commit_extensions`` parameter, so a kind that
    resolves but never commits cannot be written.
    ``test_every_component_field_has_an_installer`` pins the two together.

    The members naming a ``datafusion.user_defined`` object hold its name
    rather than the object: that module imports this one, so the lookups are
    deferred to :py:meth:`SessionContext.with_extensions`, which runs with the
    cycle long settled.
    """

    field: str
    """The ``SessionExtensionComponents`` field a bundle declares these in."""

    wrapper: str
    """Wrapper class a declaration may already be an instance of."""

    getter: str
    """Capsule getter an unwrapped declaration must expose instead."""

    factory: str
    """Helper that turns an unwrapped declaration into a wrapper."""

    label: str
    """What to call this sort of function in an error message."""


_FUNCTION_KINDS = (
    _FunctionKind(
        field="udfs",
        wrapper="ScalarUDF",
        getter="__datafusion_scalar_udf__",
        factory="udf",
        label="scalar function",
    ),
    _FunctionKind(
        field="udafs",
        wrapper="AggregateUDF",
        getter="__datafusion_aggregate_udf__",
        factory="udaf",
        label="aggregate function",
    ),
    _FunctionKind(
        field="udwfs",
        wrapper="WindowUDF",
        getter="__datafusion_window_udf__",
        factory="udwf",
        label="window function",
    ),
)
"""Every kind of function a bundle can declare, in registration order."""


def _collect_contributions(
    extensions: tuple[object, ...],
    ctx: SessionContext,
) -> tuple[list[Any], list[Any], dict[str, list[tuple[int, object, Any]]]]:
    """Run every components hook and gather what the extensions contribute.

    Validates the whole argument list before calling anything, so an argument
    that implements neither hook is refused before a well-formed extension
    ahead of it has done any work. Writes nothing to the session.

    Functions are kept paired with the extension that declared them and with
    that extension's position in the argument list, so a name claimed twice can
    name both sides and tell which remedy applies.

    Args:
        extensions: The arguments ``with_extensions`` was given.
        ctx: The context the components are bound against — the receiver, not a
            context derived from it.

    Returns:
        The logical codecs, the physical codecs, and the declared functions and
        optimizer rules as ``(position, extension, declaration)`` triples, keyed
        by the ``SessionExtensionComponents`` field they arrived in.

    Raises:
        TypeError: If an argument implements neither hook, or a hook returns
            something other than ``SessionExtensionComponents``.
    """
    for extension in extensions:
        if not isinstance(
            extension, (SessionComponentsExportable, SessionPlannerExportable)
        ):
            msg = (
                "Extension implements neither "
                "__datafusion_session_components__ nor "
                f"__datafusion_session_planner__: {extension!r}"
            )
            raise TypeError(msg)

    logical_codecs: list[LogicalExtensionCodecExportable] = []
    physical_codecs: list[PhysicalExtensionCodecExportable] = []
    declared: dict[str, list[tuple[int, object, Any]]] = {
        kind.field: [] for kind in _FUNCTION_KINDS
    }
    # Rules are not a function kind: they accumulate rather than replace, so
    # they carry no collision rule and install through their own primitive.
    declared["physical_optimizer_rules"] = []
    for position, extension in enumerate(extensions):
        if not isinstance(extension, SessionComponentsExportable):
            continue
        components = extension.__datafusion_session_components__(ctx)
        if not isinstance(components, SessionExtensionComponents):
            msg = (
                "__datafusion_session_components__ must return "
                "SessionExtensionComponents, got "
                f"{type(components).__name__} from {extension!r}"
            )
            raise TypeError(msg)
        logical_codecs.extend(components.logical_extension_codecs)
        physical_codecs.extend(components.physical_extension_codecs)
        for field_name, declarations in declared.items():
            declarations.extend(
                (position, extension, item) for item in getattr(components, field_name)
            )
    return logical_codecs, physical_codecs, declared


def _resolve_declared_functions(
    declared: list[tuple[int, object, Any]],
    wrapper: type,
    getter: str,
    factory: Any,
    label: str,
) -> list[Any]:
    """Wrap every function an extension declared, refusing a name claimed twice.

    Runs before anything is written to the session, so a bundle that hands over
    something unusable — or two bundles that both claim a name — fail with
    nothing registered. The name is read off the wrapper rather than off the
    declaration: on the FFI path the capsule reports it, and the constructor
    argument is ignored.

    Args:
        declared: ``(position, extension, function)`` triples in declaration
            order, where ``position`` indexes the ``with_extensions`` argument
            list.
        wrapper: The wrapper class a declaration may already be an instance of,
            in which case it is taken as-is.
        getter: The capsule getter an unwrapped declaration must expose.
        factory: The helper that wraps a declaration — ``udf`` and friends.
        label: What to call this sort of function in an error.

    Returns:
        The wrappers to register, in declaration order.

    Raises:
        TypeError: If a declaration is neither an instance of ``wrapper`` nor
            an object exposing ``getter``.
        ValueError: If two declarations resolve to the same name.
    """
    resolved = []
    claimed: dict[str, tuple[int, object]] = {}
    for position, extension, function in declared:
        if isinstance(function, wrapper):
            wrapped = function
        elif hasattr(function, getter):
            wrapped = factory(function)
        else:
            msg = (
                f"A declared {label} must be {wrapper.__name__} or expose "
                f"{getter}, got {function!r} from {extension!r}"
            )
            raise TypeError(msg)
        name = wrapped.name
        if name in claimed:
            # Keyed on position, not object identity, so each message names
            # the remedy its reader actually has — see
            # `extension_bundles_collisions` in the extension guide.
            claimed_at, claimed_by = claimed[name]
            if claimed_at == position:
                msg = (
                    f"{extension!r} declares two {label}s named {name!r}. "
                    "Registrations have no fall-through, so the second would "
                    "silently replace the first; rename one of them."
                )
            else:
                msg = (
                    f"Two extensions declare a {label} named {name!r}: "
                    f"argument {claimed_at} ({claimed_by!r}) and argument "
                    f"{position} ({extension!r}). Registrations have no "
                    "fall-through, so one would silently replace the other; "
                    "install them on separate sessions, or drop the repeat if "
                    "one extension was passed twice."
                )
            raise ValueError(msg)
        claimed[name] = (position, extension)
        resolved.append(wrapped)
    return resolved


def _resolve_declared_rules(
    declared: list[tuple[int, object, Any]], resolve: Any
) -> Any:
    """Import the capsule of every physical optimizer rule an extension declared.

    There is no name to check — rules accumulate — so unlike
    :py:func:`_resolve_declared_functions` this only refuses a declaration that
    cannot be a rule. The getter is looked for here rather than left to the
    importer so that the error names the bundle that declared it; a caller who
    passed four bundles cannot otherwise tell which one is at fault.

    Args:
        declared: ``(position, extension, rule)`` triples in declaration order.
        resolve: The primitive that imports a list of rules at once, returning
            an opaque object for the commit step.

    Returns:
        The imported rules, opaque, in declaration order.

    Raises:
        TypeError: If a declaration does not expose
            ``__datafusion_physical_optimizer_rule__``.
    """
    for _, extension, rule in declared:
        if not hasattr(rule, "__datafusion_physical_optimizer_rule__"):
            msg = (
                "A declared optimizer rule must expose "
                f"__datafusion_physical_optimizer_rule__, got {rule!r} "
                f"from {extension!r}"
            )
            raise TypeError(msg)
    return resolve([rule for _, _, rule in declared])


class SessionConfig:
    """Session configuration options."""

    def __init__(self, config_options: dict[str, str] | None = None) -> None:
        """Create a new :py:class:`SessionConfig` with the given configuration options.

        Each entry is applied as though passed to :py:meth:`set`, so the same
        keys are rejected. See :ref:`configuration`.

        Args:
            config_options: Options to apply, keyed by fully qualified name.

        Raises:
            ValueError: If a key names no known option, or a value does not
                parse as that option's declared type. Which of several bad
                entries is reported is not defined.

        Example usage:

        >>> from datafusion import SessionConfig, SessionContext
        >>> ctx = SessionContext(SessionConfig())
        >>> config = SessionConfig(
        ...     config_options={"datafusion.execution.batch_size": "1024"}
        ... )
        >>> ctx = SessionContext(config.with_information_schema(True))
        >>> ctx.sql(
        ...     "select value from information_schema.df_settings"
        ...     " where name = 'datafusion.execution.batch_size'"
        ... ).collect()[0]["value"][0]
        <pyarrow.StringScalar: '1024'>
        """
        self.config_internal = SessionConfigInternal(config_options)

    def with_create_default_catalog_and_schema(
        self, enabled: bool = True
    ) -> SessionConfig:
        """Control if the default catalog and schema will be automatically created.

        Args:
            enabled: Whether the default catalog and schema will be
                automatically created.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = (
            self.config_internal.with_create_default_catalog_and_schema(enabled)
        )
        return self

    def with_default_catalog_and_schema(
        self, catalog: str, schema: str
    ) -> SessionConfig:
        """Select a name for the default catalog and schema.

        Args:
            catalog: Catalog name.
            schema: Schema name.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_default_catalog_and_schema(
            catalog, schema
        )
        return self

    def with_information_schema(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the inclusion of ``information_schema`` virtual tables.

        Args:
            enabled: Whether to include ``information_schema`` virtual tables.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_information_schema(enabled)
        return self

    def with_batch_size(self, batch_size: int) -> SessionConfig:
        """Customize batch size.

        Args:
            batch_size: Batch size.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_batch_size(batch_size)
        return self

    def with_target_partitions(self, target_partitions: int) -> SessionConfig:
        """Customize the number of target partitions for query execution.

        Increasing partitions can increase concurrency.

        Args:
            target_partitions: Number of target partitions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_target_partitions(
            target_partitions
        )
        return self

    def with_repartition_aggregations(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for aggregations.

        Enabling this improves parallelism.

        Args:
            enabled: Whether to use repartitioning for aggregations.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_aggregations(
            enabled
        )
        return self

    def with_repartition_joins(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for joins to improve parallelism.

        Args:
            enabled: Whether to use repartitioning for joins.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_joins(enabled)
        return self

    def with_repartition_windows(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for window functions.

        This may improve parallelism.

        Args:
            enabled: Whether to use repartitioning for window functions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_windows(enabled)
        return self

    def with_repartition_sorts(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for window functions.

        This may improve parallelism.

        Args:
            enabled: Whether to use repartitioning for window functions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_sorts(enabled)
        return self

    def with_repartition_file_scans(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for file scans.

        Args:
            enabled: Whether to use repartitioning for file scans.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_file_scans(enabled)
        return self

    def with_repartition_file_min_size(self, size: int) -> SessionConfig:
        """Set minimum file range size for repartitioning scans.

        Args:
            size: Minimum file range size.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_file_min_size(size)
        return self

    def with_parquet_pruning(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of pruning predicate for parquet readers.

        Pruning predicates will enable the reader to skip row groups.

        Args:
            enabled: Whether to use pruning predicate for parquet readers.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_parquet_pruning(enabled)
        return self

    def set(self, key: str, value: str) -> SessionConfig:
        """Set a configuration option by its fully qualified key.

        Not every key that ``information_schema.df_settings`` lists can be set
        here: the ``datafusion.runtime.*`` entries come from the runtime
        environment rather than from the session config. See
        :ref:`configuration`.

        Args:
            key: Option key including its namespace, such as
                ``datafusion.execution.batch_size``.
            value: Option value as a string, parsed according to the type the
                option declares.

        Returns:
            This :py:class:`SessionConfig`, modified in place, so that calls
            chain.

        Raises:
            ValueError: If ``key`` names no known option, or if ``value`` does
                not parse as that option's declared type.

        Example usage:

        >>> from datafusion import SessionConfig, SessionContext
        >>> config = SessionConfig().set("datafusion.execution.batch_size", "1024")
        >>> ctx = SessionContext(config.with_information_schema(True))
        >>> ctx.sql(
        ...     "select value from information_schema.df_settings"
        ...     " where name = 'datafusion.execution.batch_size'"
        ... ).collect()[0]["value"][0]
        <pyarrow.StringScalar: '1024'>
        """
        self.config_internal = self.config_internal.set(key, value)
        return self

    def with_extension(self, extension: Any) -> SessionConfig:
        """Create a new configuration using an extension.

        Args:
            extension: A custom configuration extension object. These are
            shared from another DataFusion extension library.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_extension(extension)
        return self


class RuntimeEnvBuilder:
    """Runtime configuration options."""

    def __init__(self) -> None:
        """Create a new :py:class:`RuntimeEnvBuilder` with default values."""
        self.config_internal = RuntimeEnvBuilderInternal()

    def with_disk_manager_disabled(self) -> RuntimeEnvBuilder:
        """Disable the disk manager, attempts to create temporary files will error.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_disk_manager_disabled()
        return self

    def with_disk_manager_os(self) -> RuntimeEnvBuilder:
        """Use the operating system's temporary directory for disk manager.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_disk_manager_os()
        return self

    def with_disk_manager_specified(
        self, *paths: str | pathlib.Path
    ) -> RuntimeEnvBuilder:
        """Use the specified paths for the disk manager's temporary files.

        Args:
            paths: Paths to use for the disk manager's temporary files.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        paths_list = [str(p) for p in paths]
        self.config_internal = self.config_internal.with_disk_manager_specified(
            paths_list
        )
        return self

    def with_unbounded_memory_pool(self) -> RuntimeEnvBuilder:
        """Use an unbounded memory pool.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_unbounded_memory_pool()
        return self

    def with_fair_spill_pool(self, size: int) -> RuntimeEnvBuilder:
        """Use a fair spill pool with the specified size.

        This pool works best when you know beforehand the query has multiple spillable
        operators that will likely all need to spill. Sometimes it will cause spills
        even when there was sufficient memory (reserved for other operators) to avoid
        doing so::

            ┌───────────────────────z──────────────────────z───────────────┐
            │                       z                      z               │
            │                       z                      z               │
            │       Spillable       z       Unspillable    z     Free      │
            │        Memory         z        Memory        z    Memory     │
            │                       z                      z               │
            │                       z                      z               │
            └───────────────────────z──────────────────────z───────────────┘

        Args:
            size: Size of the memory pool in bytes.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_fair_spill_pool(1024)
        """
        self.config_internal = self.config_internal.with_fair_spill_pool(size)
        return self

    def with_greedy_memory_pool(self, size: int) -> RuntimeEnvBuilder:
        """Use a greedy memory pool with the specified size.

        This pool works well for queries that do not need to spill or have a single
        spillable operator. See :py:func:`with_fair_spill_pool` if there are
        multiple spillable operators that all will spill.

        Args:
            size: Size of the memory pool in bytes.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_greedy_memory_pool(1024)
        """
        self.config_internal = self.config_internal.with_greedy_memory_pool(size)
        return self

    def with_temp_file_path(self, path: str | pathlib.Path) -> RuntimeEnvBuilder:
        """Use the specified path to create any needed temporary files.

        Args:
            path: Path to use for temporary files.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_temp_file_path("/tmp")
        """
        self.config_internal = self.config_internal.with_temp_file_path(str(path))
        return self


class SQLOptions:
    """Options to be used when performing SQL queries."""

    def __init__(self) -> None:
        """Create a new :py:class:`SQLOptions` with default values.

        The default values are:
        - DDL commands are allowed
        - DML commands are allowed
        - Statements are allowed
        """
        self.options_internal = SQLOptionsInternal()

    def with_allow_ddl(self, allow: bool = True) -> SQLOptions:
        """Should DDL (Data Definition Language) commands be run?

        Examples of DDL commands include ``CREATE TABLE`` and ``DROP TABLE``.

        Args:
            allow: Allow DDL commands to be run.

        Returns:
            A new :py:class:`SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_ddl(True)
        """
        self.options_internal = self.options_internal.with_allow_ddl(allow)
        return self

    def with_allow_dml(self, allow: bool = True) -> SQLOptions:
        """Should DML (Data Manipulation Language) commands be run?

        Examples of DML commands include ``INSERT INTO`` and ``DELETE``.

        Args:
            allow: Allow DML commands to be run.

        Returns:
            A new :py:class:`SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_dml(True)
        """
        self.options_internal = self.options_internal.with_allow_dml(allow)
        return self

    def with_allow_statements(self, allow: bool = True) -> SQLOptions:
        """Should statements such as ``SET VARIABLE`` and ``BEGIN TRANSACTION`` be run?

        Args:
            allow: Allow statements to be run.

        Returns:
            A new :py:class:SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_statements(True)
        """
        self.options_internal = self.options_internal.with_allow_statements(allow)
        return self


class SessionContext:
    """This is the main interface for executing queries and creating DataFrames.

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

    **A context is a handle on a session, not the session itself.** The
    ``with_*`` methods — :py:meth:`with_logical_extension_codec`,
    :py:meth:`with_physical_extension_codec`,
    :py:meth:`with_python_udf_inlining`, and :py:meth:`with_extensions` —
    return a new context wrapping the *same* underlying session. Only the
    Python-side codec settings differ; catalogs, tables, registered functions,
    and configuration are the one shared session, so a registration through
    either handle is visible to both.

    A few things therefore belong to the session rather than to a handle, and
    take effect even if the handle that set them is discarded: the query
    planner (see :py:meth:`set_query_planner`), and the rebuild of an installed
    foreign planner that follows installing a codec. :ref:`extension_sessions`
    in the online documentation works through when that matters.

    **Keep a context alive for as long as anything derived from it is in use.**
    A :py:class:`~datafusion.DataFrame`, logical plan, or exported capsule does
    not extend the session's lifetime. Once the last context on a session is
    collected, any operation that reaches an extension codec fails with
    ``TaskContextProvider went out of scope over FFI boundary``.
    """

    def __init__(
        self,
        config: SessionConfig | None = None,
        runtime: RuntimeEnvBuilder | None = None,
    ) -> None:
        """Main interface for executing queries with DataFusion.

        Maintains the state of the connection between a user and an instance
        of the connection between a user and an instance of the DataFusion
        engine.

        Args:
            config: Session configuration options.
            runtime: Runtime configuration options.

        Example usage:

        The following example demonstrates how to use the context to execute
        a query against a CSV data source using the :py:class:`DataFrame` API::

            from datafusion import SessionContext

            ctx = SessionContext()
            df = ctx.read_csv("data.csv")
        """
        config = config.config_internal if config is not None else None
        runtime = runtime.config_internal if runtime is not None else None

        self.ctx = SessionContextInternal(config, runtime)

    def __repr__(self) -> str:
        """Print a string representation of the Session Context."""
        return self.ctx.__repr__()

    @classmethod
    def global_ctx(cls) -> SessionContext:
        """Retrieve the global context as a `SessionContext` wrapper.

        Returns:
            A `SessionContext` object that wraps the global `SessionContextInternal`.
        """
        internal_ctx = SessionContextInternal.global_ctx()
        wrapper = cls()
        wrapper.ctx = internal_ctx
        return wrapper

    def enable_url_table(self) -> SessionContext:
        """Control if local files can be queried as tables.

        Returns:
            A new :py:class:`SessionContext` object with url table enabled.
        """
        klass = self.__class__
        obj = klass.__new__(klass)
        obj.ctx = self.ctx.enable_url_table()
        return obj

    def register_object_store(
        self, schema: str, store: Any, host: str | None = None
    ) -> None:
        """Add a new object store into the session.

        Args:
            schema: The data source schema.
            store: The :py:class:`~datafusion.object_store.ObjectStore` to register.
            host: URL for the host.
        """
        self.ctx.register_object_store(schema, store, host)

    def deregister_object_store(self, schema: str, host: str | None = None) -> None:
        """Remove an object store from the session.

        Args:
            schema: The data source schema (e.g. ``"s3://"``).
            host: URL for the host (e.g. bucket name).
        """
        self.ctx.deregister_object_store(schema, host)

    def _register_object_store_for_path(
        self, path: str | pathlib.Path, store: Any
    ) -> None:
        """Parse a URL path and register the given object store for its scheme and host.

        This is a convenience helper used by methods like
        :py:meth:`register_parquet` and :py:meth:`read_parquet` to
        automatically register an object store when an ``object_store``
        parameter is provided.

        Args:
            path: A URL-style path (e.g. ``"s3://bucket/key.parquet"`` or
                ``"file:///tmp/data.parquet"``).
            store: An object store instance to register.

        Raises:
            ValueError: If the path does not contain a URL scheme, or if
                a non-file scheme is missing a host/bucket component.
        """
        parsed = urlparse(str(path))
        if not parsed.scheme:
            msg = (
                f"Cannot determine object store URL from path {path!r}. "
                "The path must use a URL scheme (e.g. 's3://bucket/key')."
            )
            raise ValueError(msg)
        # file:// URLs typically have an empty netloc (e.g. file:///tmp/a.parquet)
        # For other schemes (s3, gs, az, https) the netloc (bucket/host) is required.
        if parsed.scheme != "file" and not parsed.netloc:
            msg = (
                f"Cannot determine object store URL from path {path!r}. "
                "The path must include a host or bucket "
                "(e.g. 's3://bucket/key')."
            )
            raise ValueError(msg)
        scheme = f"{parsed.scheme}://"
        host = parsed.netloc or None
        self.register_object_store(scheme, store, host=host)

    def register_listing_table(
        self,
        name: str,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_extension: str = ".parquet",
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
    ) -> None:
        """Register multiple files as a single table.

        Registers a :py:class:`~datafusion.catalog.Table` that can assemble multiple
        files from locations in an :py:class:`~datafusion.object_store.ObjectStore`
        instance.

        Args:
            name: Name of the resultant table.
            path: Path to the file to register.
            table_partition_cols: Partition columns.
            file_extension: File extension of the provided table.
            schema: The data source schema.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
        """
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_listing_table(
            name,
            path,
            table_partition_cols,
            file_extension,
            schema,
            self._convert_file_sort_order(file_sort_order),
        )

    def sql(
        self,
        query: str,
        options: SQLOptions | None = None,
        param_values: dict[str, Any] | None = None,
        **named_params: Any,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.DataFrame` from SQL query text.

        See the online documentation for a description of how to perform
        parameterized substitution via either the ``param_values`` option
        or passing in ``named_params``.

        Note: This API implements DDL statements such as ``CREATE TABLE`` and
        ``CREATE VIEW`` and DML statements such as ``INSERT INTO`` with in-memory
        default implementation.See
        :py:func:`~datafusion.context.SessionContext.sql_with_options`.

        Args:
            query: SQL query text.
            options: If provided, the query will be validated against these options.
            param_values: Provides substitution of scalar values in the query
                after parsing.
            named_params: Provides string or DataFrame substitution in the query string.

        Returns:
            DataFrame representation of the SQL query.
        """

        def value_to_scalar(value: Any) -> pa.Scalar:
            if isinstance(value, pa.Scalar):
                return value
            return pa.scalar(value)

        def value_to_string(value: Any) -> str:
            if isinstance(value, DataFrame):
                view_name = str(uuid.uuid4()).replace("-", "_")
                view_name = f"view_{view_name}"
                view = value.df.into_view(temporary=True)
                self.ctx.register_table(view_name, view)
                return view_name
            return str(value)

        param_values = (
            {name: value_to_scalar(value) for (name, value) in param_values.items()}
            if param_values is not None
            else {}
        )
        param_strings = (
            {name: value_to_string(value) for (name, value) in named_params.items()}
            if named_params is not None
            else {}
        )

        options_raw = options.options_internal if options is not None else None

        return DataFrame(
            self.ctx.sql_with_options(
                query,
                options=options_raw,
                param_values=param_values,
                param_strings=param_strings,
            )
        )

    def sql_with_options(
        self,
        query: str,
        options: SQLOptions,
        param_values: dict[str, Any] | None = None,
        **named_params: Any,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from SQL query text.

        This function will first validate that the query is allowed by the
        provided options.

        Args:
            query: SQL query text.
            options: SQL options.
            param_values: Provides substitution of scalar values in the query
                after parsing.
            named_params: Provides string or DataFrame substitution in the query string.

        Returns:
            DataFrame representation of the SQL query.
        """
        return self.sql(
            query, options=options, param_values=param_values, **named_params
        )

    def create_dataframe(
        self,
        partitions: list[list[pa.RecordBatch]],
        name: str | None = None,
        schema: pa.Schema | None = None,
    ) -> DataFrame:
        """Create and return a dataframe using the provided partitions.

        Args:
            partitions: :py:class:`pa.RecordBatch` partitions to register.
            name: Resultant dataframe name.
            schema: Schema for the partitions.

        Returns:
            DataFrame representation of the SQL query.
        """
        return DataFrame(self.ctx.create_dataframe(partitions, name, schema))

    def create_dataframe_from_logical_plan(self, plan: LogicalPlan) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from an existing plan.

        Args:
            plan: Logical plan.

        Returns:
            DataFrame representation of the logical plan.
        """
        return DataFrame(self.ctx.create_dataframe_from_logical_plan(plan._raw_plan))

    def from_pylist(
        self, data: list[dict[str, Any]], name: str | None = None
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a list.

        Args:
            data: List of dictionaries.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the list of dictionaries.
        """
        return DataFrame(self.ctx.from_pylist(data, name))

    def from_pydict(
        self, data: dict[str, list[Any]], name: str | None = None
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a dictionary.

        Args:
            data: Dictionary of lists.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the dictionary of lists.
        """
        return DataFrame(self.ctx.from_pydict(data, name))

    def from_arrow(
        self,
        data: ArrowStreamExportable | ArrowArrayExportable,
        name: str | None = None,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from an Arrow source.

        The Arrow data source can be any object that implements either
        ``__arrow_c_stream__`` or ``__arrow_c_array__``. For the latter, it must return
        a struct array.

        Arrow data can be Polars, Pandas, Pyarrow etc.

        Args:
            data: Arrow data source.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Arrow table.
        """
        return DataFrame(self.ctx.from_arrow(data, name))

    def from_pandas(self, data: pd.DataFrame, name: str | None = None) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a Pandas DataFrame.

        Args:
            data: Pandas DataFrame.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Pandas DataFrame.
        """
        return DataFrame(self.ctx.from_pandas(data, name))

    def from_polars(self, data: pl.DataFrame, name: str | None = None) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a Polars DataFrame.

        Args:
            data: Polars DataFrame.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Polars DataFrame.
        """
        return DataFrame(self.ctx.from_polars(data, name))

    # https://github.com/apache/datafusion-python/pull/1016#discussion_r1983239116
    # is the discussion on how we arrived at adding register_view
    def register_view(self, name: str, df: DataFrame) -> None:
        """Register a :py:class:`~datafusion.dataframe.DataFrame` as a view.

        Args:
            name (str): The name to register the view under.
            df (DataFrame): The DataFrame to be converted into a view and registered.
        """
        view = df.into_view()
        self.ctx.register_table(name, view)

    def register_table(
        self,
        name: str,
        table: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset,
    ) -> None:
        """Register a :py:class:`~datafusion.Table` with this context.

        The registered table can be referenced from SQL statements executed against
        this context.

        Args:
            name: Name of the resultant table.
            table: Any object that can be converted into a :class:`Table`.
        """
        self.ctx.register_table(name, table)

    def deregister_table(self, name: str) -> None:
        """Remove a table from the session."""
        self.ctx.deregister_table(name)

    def register_table_factory(
        self,
        format: str,
        factory: TableProviderFactory | TableProviderFactoryExportable,
    ) -> None:
        """Register a :py:class:`~datafusion.TableProviderFactoryExportable`.

        The registered factory can be referenced from SQL DDL statements executed
        against this context.

        Args:
            format: The value to be used in `STORED AS ${format}` clause.
            factory: A PyCapsule that implements :class:`TableProviderFactoryExportable`
        """
        self.ctx.register_table_factory(format, factory)

    def catalog_names(self) -> set[str]:
        """Returns the list of catalogs in this context."""
        return self.ctx.catalog_names()

    def register_catalog_provider_list(
        self,
        provider: CatalogProviderListExportable | CatalogProviderList | CatalogList,
    ) -> None:
        """Register a catalog provider list."""
        if isinstance(provider, CatalogList):
            self.ctx.register_catalog_provider_list(provider.catalog)
        else:
            self.ctx.register_catalog_provider_list(provider)

    def register_catalog_provider(
        self, name: str, provider: CatalogProviderExportable | CatalogProvider | Catalog
    ) -> None:
        """Register a catalog provider."""
        if isinstance(provider, Catalog):
            self.ctx.register_catalog_provider(name, provider.catalog)
        else:
            self.ctx.register_catalog_provider(name, provider)

    @deprecated("Use register_table() instead.")
    def register_table_provider(
        self,
        name: str,
        provider: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset,
    ) -> None:
        """Register a table provider.

        Deprecated: use :meth:`register_table` instead.
        """
        self.register_table(name, provider)

    def register_udtf(self, func: TableFunction) -> None:
        """Register a user defined table function."""
        self.ctx.register_udtf(func._udtf)

    def register_batch(self, name: str, batch: pa.RecordBatch) -> None:
        """Register a single :py:class:`pa.RecordBatch` as a table.

        Args:
            name: Name of the resultant table.
            batch: Record batch to register as a table.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"a": [1, 2, 3]})
            >>> ctx.register_batch("batch_tbl", batch)
            >>> ctx.sql("SELECT * FROM batch_tbl").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        self.ctx.register_batch(name, batch)

    def deregister_udtf(self, name: str) -> None:
        """Remove a user-defined table function from the session.

        Args:
            name: Name of the UDTF to deregister.
        """
        self.ctx.deregister_udtf(name)

    def register_record_batches(
        self, name: str, partitions: list[list[pa.RecordBatch]]
    ) -> None:
        """Register record batches as a table.

        This function will convert the provided partitions into a table and
        register it into the session using the given name.

        Args:
            name: Name of the resultant table.
            partitions: Record batches to register as a table.
        """
        self.ctx.register_record_batches(name, partitions)

    def read_batch(self, batch: pa.RecordBatch) -> DataFrame:
        """Return a :py:class:`~datafusion.DataFrame` reading a single batch.

        Convenience wrapper around :py:meth:`read_batches` for the single-batch
        case. Unlike :py:meth:`register_batch`, this does not register the
        batch as a named table; it returns an anonymous
        :py:class:`~datafusion.DataFrame` directly.

        Args:
            batch: Record batch to wrap as a DataFrame.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"a": [1, 2, 3]})
            >>> ctx.read_batch(batch).to_pydict()
            {'a': [1, 2, 3]}
        """
        return self.read_batches([batch])

    def read_batches(self, batches: Iterable[pa.RecordBatch]) -> DataFrame:
        """Return a :py:class:`~datafusion.DataFrame` reading the given batches.

        All batches must share the same schema. Any iterable of
        :py:class:`pa.RecordBatch` is accepted (list, tuple, generator);
        it is materialized into a list before being handed to the
        underlying Rust binding. Unlike :py:meth:`register_record_batches`,
        this does not register the batches as a named table; it returns
        an anonymous :py:class:`~datafusion.DataFrame` directly.

        Args:
            batches: Record batches to wrap as a DataFrame.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> b1 = pa.RecordBatch.from_pydict({"a": [1, 2]})
            >>> b2 = pa.RecordBatch.from_pydict({"a": [3, 4]})
            >>> ctx.read_batches([b1, b2]).to_pydict()
            {'a': [1, 2, 3, 4]}

            A generator works too:

            >>> ctx.read_batches(b for b in [b1, b2]).to_pydict()
            {'a': [1, 2, 3, 4]}
        """
        return DataFrame(self.ctx.read_batches(list(batches)))

    def register_parquet(
        self,
        name: str,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        parquet_pruning: bool = True,
        file_extension: str = ".parquet",
        skip_metadata: bool = True,
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a Parquet file as a table.

        The registered table can be referenced from SQL statement executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the Parquet file.
            table_partition_cols: Partition columns.
            parquet_pruning: Whether the parquet reader should use the
                predicate to prune row groups.
            file_extension: File extension; only files with this extension are
                selected for data input.
            skip_metadata: Whether the parquet reader should skip any metadata
                that may be in the file schema. This can help avoid schema
                conflicts due to metadata.
            schema: The data source schema.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
            object_store: A pre-configured object store instance (e.g.
                :py:class:`~datafusion.object_store.AmazonS3`,
                :py:class:`~datafusion.object_store.GoogleCloud`,
                :py:class:`~datafusion.object_store.MicrosoftAzure`) to use
                for accessing the file. When provided, the store is
                automatically registered for the URL scheme and host parsed
                from ``path``, removing the need to call
                :py:meth:`register_object_store` separately. This is
                especially useful in multi-threaded environments where
                setting credentials via ``os.environ`` is not thread-safe.

        Examples:
            Register a local Parquet file:

            >>> import datafusion
            >>> ctx = datafusion.SessionContext()
            >>> ctx.register_parquet("my_table", "data.parquet")  # doctest: +SKIP

            Register from S3 with inline credentials (thread-safe):

            >>> from datafusion.object_store import AmazonS3  # doctest: +SKIP
            >>> store = AmazonS3(
            ...     bucket_name="my-bucket",
            ...     region="us-east-1",
            ...     access_key_id="...",
            ...     secret_access_key="...",
            ... )  # doctest: +SKIP
            >>> ctx.register_parquet(
            ...     "my_table",
            ...     "s3://my-bucket/data.parquet",
            ...     object_store=store,
            ... )  # doctest: +SKIP
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_parquet(
            name,
            path,
            table_partition_cols,
            parquet_pruning,
            file_extension,
            skip_metadata,
            schema,
            self._convert_file_sort_order(file_sort_order),
        )

    def register_csv(
        self,
        name: str,
        path: str | pathlib.Path | list[str | pathlib.Path],
        schema: pa.Schema | None = None,
        has_header: bool = True,
        delimiter: str = ",",
        schema_infer_max_records: int = DEFAULT_MAX_INFER_SCHEMA,
        file_extension: str = ".csv",
        file_compression_type: str | None = None,
        options: CsvReadOptions | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a CSV file as a table.

        The registered table can be referenced from SQL statement executed against.

        Args:
            name: Name of the table to register.
            path: Path to the CSV file. It also accepts a list of Paths.
            schema: An optional schema representing the CSV file. If None, the
                CSV reader will try to infer it based on data in file.
            has_header: Whether the CSV file have a header. If schema inference
                is run on a file with no headers, default column names are
                created.
            delimiter: An optional column delimiter.
            schema_infer_max_records: Maximum number of rows to read from CSV
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            file_compression_type: File compression type.
            options: Set advanced options for CSV reading. This cannot be
                combined with any of the other options in this method.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            # For list paths, register from the first entry
            register_path = path[0] if isinstance(path, list) else path
            self._register_object_store_for_path(register_path, object_store)
        if options is not None and (
            schema is not None
            or not has_header
            or delimiter != ","
            or schema_infer_max_records != DEFAULT_MAX_INFER_SCHEMA
            or file_extension != ".csv"
            or file_compression_type is not None
        ):
            message = (
                "Combining CsvReadOptions parameter with additional options "
                "is not supported. Use CsvReadOptions to set parameters."
            )
            warnings.warn(
                message,
                category=UserWarning,
                stacklevel=2,
            )

        options = (
            options
            if options is not None
            else CsvReadOptions(
                schema=schema,
                has_header=has_header,
                delimiter=delimiter,
                schema_infer_max_records=schema_infer_max_records,
                file_extension=file_extension,
                file_compression_type=file_compression_type,
            )
        )

        self.ctx.register_csv(
            name,
            path,
            options.to_inner(),
        )

    def register_json(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        schema_infer_max_records: int = 1000,
        file_extension: str = ".json",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a JSON file as a table.

        The registered table can be referenced from SQL statement executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the JSON file.
            schema: The data source schema.
            schema_infer_max_records: Maximum number of rows to read from JSON
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            table_partition_cols: Partition columns.
            file_compression_type: File compression type.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_json(
            name,
            path,
            schema,
            schema_infer_max_records,
            file_extension,
            table_partition_cols,
            file_compression_type,
        )

    def register_avro(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".avro",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register an Avro file as a table.

        The registered table can be referenced from SQL statement executed against
        this context.

        Args:
            name: Name of the table to register.
            path: Path to the Avro file.
            schema: The data source schema.
            file_extension: File extension to select.
            table_partition_cols:  Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_avro(name, path, schema, file_extension, table_partition_cols)

    def register_arrow(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".arrow",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register an Arrow IPC file as a table.

        The registered table can be referenced from SQL statements executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the Arrow IPC file.
            schema: The data source schema.
            file_extension: File extension to select.
            table_partition_cols: Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Examples:
            >>> import tempfile, os
            >>> ctx = dfn.SessionContext()
            >>> table = pa.table({"x": [10, 20, 30]})
            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow("arrow_tbl", path)
            ...     ctx.sql("SELECT * FROM arrow_tbl").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]

            Provide an explicit ``schema`` to override schema inference:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow(
            ...         "arrow_schema",
            ...         path,
            ...         schema=pa.schema([("x", pa.int64())]),
            ...     )
            ...     ctx.sql("SELECT * FROM arrow_schema").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]

            Use ``file_extension`` to read files with a non-default extension:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.ipc")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow(
            ...         "arrow_ipc", path, file_extension=".ipc"
            ...     )
            ...     ctx.sql("SELECT * FROM arrow_ipc").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_arrow(
            name, path, schema, file_extension, table_partition_cols
        )

    def register_dataset(self, name: str, dataset: pa.dataset.Dataset) -> None:
        """Register a :py:class:`pa.dataset.Dataset` as a table.

        Args:
            name: Name of the table to register.
            dataset: PyArrow dataset.
        """
        self.ctx.register_dataset(name, dataset)

    def register_udf(self, udf: ScalarUDF) -> None:
        """Register a user-defined function (UDF) with the context."""
        self.ctx.register_udf(udf._udf)

    def deregister_udf(self, name: str) -> None:
        """Remove a user-defined scalar function from the session.

        Args:
            name: Name of the UDF to deregister.
        """
        self.ctx.deregister_udf(name)

    def register_udaf(self, udaf: AggregateUDF) -> None:
        """Register a user-defined aggregation function (UDAF) with the context."""
        self.ctx.register_udaf(udaf._udaf)

    def enable_spark_functions(self) -> None:
        """Register all Spark-compatible functions for SQL access.

        Registers every UDF/UDAF/UDWF from the ``datafusion-spark`` crate,
        overriding any DataFusion built-ins of the same name with their
        Spark-semantics version (e.g. ``substring`` becomes 1-indexed,
        ``concat`` propagates NULL, ``round`` uses HALF_UP rounding).

        For DataFrame use, import the typed wrappers from
        :py:mod:`datafusion.functions.spark` directly; this method is only
        needed for SQL queries.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> ctx.enable_spark_functions()
            >>> ctx.sql(
            ...     "SELECT sha2('hello', 256) AS h"
            ... ).collect_column("h")[0].as_py()
            '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
        """
        self.ctx.enable_spark_functions()

    def deregister_udaf(self, name: str) -> None:
        """Remove a user-defined aggregate function from the session.

        Args:
            name: Name of the UDAF to deregister.
        """
        self.ctx.deregister_udaf(name)

    def register_udwf(self, udwf: WindowUDF) -> None:
        """Register a user-defined window function (UDWF) with the context."""
        self.ctx.register_udwf(udwf._udwf)

    def deregister_udwf(self, name: str) -> None:
        """Remove a user-defined window function from the session.

        Args:
            name: Name of the UDWF to deregister.
        """
        self.ctx.deregister_udwf(name)

    def udf(self, name: str) -> ScalarUDF:
        """Look up a registered scalar UDF by name.

        Returns the same ``ScalarUDF`` wrapper that :py:meth:`register_udf`
        accepts, so it can be invoked as an expression in the DataFrame API
        or re-registered into a different :py:class:`SessionContext`.
        Built-in scalar functions from the session's function registry are
        also looked up.

        Args:
            name: Name of the registered scalar UDF.

        Raises:
            KeyError: If no scalar UDF is registered under ``name``.

        Examples:
            Register a UDF, then look it up by name and use it in the
            DataFrame API:

            >>> ctx = dfn.SessionContext()
            >>> nullcheck = dfn.udf(
            ...     lambda x: x.is_null(),
            ...     [pa.int64()],
            ...     pa.bool_(),
            ...     volatility="immutable",
            ...     name="nullcheck",
            ... )
            >>> ctx.register_udf(nullcheck)
            >>> fn = ctx.udf("nullcheck")
            >>> df = ctx.from_pydict({"a": [1, None, 3]})
            >>> df.select(fn(col("a")).alias("is_null")).to_pydict()
            {'is_null': [False, True, False]}

            Late-binding: the function name can come from configuration
            rather than an imported symbol, which is useful when the set
            of UDFs is plugin-driven or chosen at runtime:

            >>> config = {"null_check": "nullcheck"}
            >>> fn = ctx.udf(config["null_check"])
            >>> df.select(fn(col("a")).alias("is_null")).to_pydict()
            {'is_null': [False, True, False]}
        """
        from datafusion.user_defined import ScalarUDF as _ScalarUDF  # noqa: PLC0415

        return _ScalarUDF._from_internal(self.ctx.udf(name))

    def udaf(self, name: str) -> AggregateUDF:
        """Look up a registered aggregate UDF by name.

        Returns the same ``AggregateUDF`` wrapper that :py:meth:`register_udaf`
        accepts. Built-in aggregate functions such as ``sum`` or ``avg`` are
        also discoverable through this lookup. See :py:meth:`udf` for a worked
        late-binding example; the pattern is identical for aggregates.

        Args:
            name: Name of the registered aggregate UDF.

        Raises:
            KeyError: If no aggregate UDF is registered under ``name``.

        Examples:
            Look up a built-in aggregate by name and use it in
            :py:meth:`~datafusion.DataFrame.aggregate`:

            >>> ctx = dfn.SessionContext()
            >>> sum_fn = ctx.udaf("sum")
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> df.aggregate([], [sum_fn(col("a")).alias("total")]).to_pydict()
            {'total': [6]}
        """
        from datafusion.user_defined import (  # noqa: PLC0415
            AggregateUDF as _AggregateUDF,
        )

        return _AggregateUDF._from_internal(self.ctx.udaf(name))

    def udwf(self, name: str) -> WindowUDF:
        """Look up a registered window UDF by name.

        Returns the same ``WindowUDF`` wrapper that :py:meth:`register_udwf`
        accepts. Built-in window functions such as ``row_number`` or ``rank``
        are also discoverable through this lookup. See :py:meth:`udf` for a
        worked late-binding example; the pattern is identical for window
        functions.

        Args:
            name: Name of the registered window UDF.

        Raises:
            KeyError: If no window UDF is registered under ``name``.

        Examples:
            Look up a built-in window function by name and use it in
            ``select``:

            >>> ctx = dfn.SessionContext()
            >>> rn = ctx.udwf("row_number")
            >>> df = ctx.from_pydict({"a": [10, 20, 30]})
            >>> df.select(col("a"), rn().alias("rn")).to_pydict()
            {'a': [10, 20, 30], 'rn': [1, 2, 3]}
        """
        from datafusion.user_defined import WindowUDF as _WindowUDF  # noqa: PLC0415

        return _WindowUDF._from_internal(self.ctx.udwf(name))

    def udfs(self) -> list[str]:
        """Return the sorted names of all registered scalar UDFs.

        Includes both user-registered and built-in scalar functions. Pair
        with :py:meth:`udf` to drive discovery, validation, or config-based
        dispatch.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "abs" in ctx.udfs()
            True
        """
        return self.ctx.udfs()

    def udafs(self) -> list[str]:
        """Return the sorted names of all registered aggregate UDFs.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "sum" in ctx.udafs()
            True
        """
        return self.ctx.udafs()

    def udwfs(self) -> list[str]:
        """Return the sorted names of all registered window UDFs.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "row_number" in ctx.udwfs()
            True
        """
        return self.ctx.udwfs()

    def catalog(self, name: str = "datafusion") -> Catalog:
        """Retrieve a catalog by name."""
        return Catalog(self.ctx.catalog(name))

    def table(self, name: str) -> DataFrame:
        """Retrieve a previously registered table by name."""
        return DataFrame(self.ctx.table(name))

    def table_exist(self, name: str) -> bool:
        """Return whether a table with the given name exists."""
        return self.ctx.table_exist(name)

    def empty_table(self) -> DataFrame:
        """Create an empty :py:class:`~datafusion.dataframe.DataFrame`."""
        return DataFrame(self.ctx.empty_table())

    def session_id(self) -> str:
        """Return an id that uniquely identifies this :py:class:`SessionContext`."""
        return self.ctx.session_id()

    def session_start_time(self) -> str:
        """Return the session start time as an RFC 3339 formatted string.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.session_start_time()  # doctest: +SKIP
            '2026-01-01T12:34:56.123456789+00:00'
        """
        return self.ctx.session_start_time()

    def enable_ident_normalization(self) -> bool:
        """Return whether identifier normalization (lowercasing) is enabled.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.enable_ident_normalization()
            True
        """
        return self.ctx.enable_ident_normalization()

    def copied_config(self) -> SessionConfig:
        """Return a copy of the active :py:class:`SessionConfig`.

        Mutating the returned config does not affect this context; use
        the result when you need a starting point for a new context or
        want to inspect the current settings independent of further
        changes here.

        Examples:
            >>> ctx = SessionContext(SessionConfig().with_batch_size(1024))
            >>> isinstance(ctx.copied_config(), SessionConfig)
            True
        """
        config = SessionConfig()
        config.config_internal = self.ctx.copied_config()
        return config

    @staticmethod
    def parse_capacity_limit(config_name: str, limit: str) -> int:
        """Parse a size string into a byte count.

        Accepts strings like ``"100M"``, ``"1.5G"``, or ``"512K"``.
        ``"0"`` is accepted and returns 0. ``config_name`` is used purely
        for error messages and identifies which configuration setting the
        limit belongs to. Use this helper when constructing a
        :py:class:`RuntimeEnvBuilder` from a human-friendly size string.

        Examples:
            >>> SessionContext.parse_capacity_limit(
            ...     "datafusion.runtime.memory_limit", "1M"
            ... )
            1048576
            >>> SessionContext.parse_capacity_limit(
            ...     "datafusion.runtime.memory_limit", "0"
            ... )
            0
        """
        return SessionContextInternal.parse_capacity_limit(config_name, limit)

    def parse_sql_expr(self, sql: str, schema: DFSchema) -> Expr:
        """Parse a SQL expression string into a logical expression.

        Args:
            sql: SQL expression string.
            schema: Schema to use for resolving column references.

        Returns:
            Parsed expression.

        Examples:
            >>> from datafusion.common import DFSchema
            >>> ctx = SessionContext()
            >>> schema = DFSchema.empty()
            >>> ctx.parse_sql_expr("1 + 2", schema=schema)
            Expr(Int64(1) + Int64(2))
        """
        from datafusion.expr import Expr  # noqa: PLC0415

        return Expr(self.ctx.parse_sql_expr(sql, schema))

    def execute_logical_plan(self, plan: LogicalPlan) -> DataFrame:
        """Execute a :py:class:`~datafusion.plan.LogicalPlan` and return a DataFrame.

        Args:
            plan: Logical plan to execute.

        Returns:
            DataFrame resulting from the execution.

        Examples:
            >>> ctx = SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> plan = df.logical_plan()
            >>> df2 = ctx.execute_logical_plan(plan)
            >>> df2.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        return DataFrame(self.ctx.execute_logical_plan(plan._raw_plan))

    def refresh_catalogs(self) -> None:
        """Refresh catalog metadata.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.refresh_catalogs()
        """
        self.ctx.refresh_catalogs()

    def remove_optimizer_rule(self, name: str) -> bool:
        """Remove an optimizer rule by name.

        Args:
            name: Name of the optimizer rule to remove.

        Returns:
            True if a rule with the given name was found and removed.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.remove_optimizer_rule("nonexistent_rule")
            False
        """
        return self.ctx.remove_optimizer_rule(name)

    def add_physical_optimizer_rule(
        self, rule: PhysicalOptimizerRuleExportable
    ) -> None:
        """Append a user-defined physical optimizer rule to the session.

        The rule is imported via its ``__datafusion_physical_optimizer_rule__``
        PyCapsule, typically produced by a separate compiled extension. The
        underlying :class:`SessionState` is rebuilt from its current state
        with the new rule appended, so previously registered tables, UDFs,
        and catalogs are preserved. Prepared statements are not — see
        :ref:`extension_rule_rebuild`.

        Args:
            rule: Object exposing ``__datafusion_physical_optimizer_rule__``,
                a :class:`PhysicalOptimizerRuleExportable`.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> from my_extension import MyPhysicalOptimizerRule  # doctest: +SKIP
            >>> rule = MyPhysicalOptimizerRule()  # doctest: +SKIP
            >>> ctx.add_physical_optimizer_rule(rule)  # doctest: +SKIP
        """
        self.ctx.add_physical_optimizer_rule(rule)

    def set_query_planner(self, planner: QueryPlannerExportable | _PyCapsule) -> None:
        """Install a custom query planner on this session.

        The planner is imported through its ``__datafusion_query_planner__``
        PyCapsule, in the same way
        :meth:`~SessionContext.add_physical_optimizer_rule` installs a rule.

        Returns nothing, because the planner lives in the session rather than
        in a handle on it — installing one is visible to every context sharing
        that session, including ones an earlier ``with_*`` call returned. See
        :py:class:`SessionContext`.

        A session holds exactly one planner, so calling this again **replaces**
        the previous one rather than layering. To chain planners, have the new
        planner wrap the capsule from
        :meth:`~SessionContext.__datafusion_query_planner__`, captured *before*
        the new planner is installed.

        Install any extension codecs before a layered planner; the rebuild that
        follows a later codec install does not reach the fallback inside one.
        See :ref:`planner_codec_rebinding`, or prefer
        :py:meth:`with_extensions`, which cannot capture a partial chain.

        Args:
            planner: Object exposing ``__datafusion_query_planner__`` (see
                :py:class:`~datafusion.extensions.QueryPlannerExportable`) or a raw
                ``datafusion_query_planner`` PyCapsule.

        Raises:
            ValueError: If the capsule is not named ``datafusion_query_planner``.

        Examples:
            A session exports its own planner, which is what you capture to
            wrap:

            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> fallback = ctx.__datafusion_query_planner__()
            >>> type(fallback).__name__
            'PyCapsule'

            Skipped here (needs a built extension library):

            >>> from my_extension import DistributedQueryPlanner  # doctest: +SKIP
            >>> ctx.set_query_planner(
            ...     DistributedQueryPlanner(fallback=fallback)
            ... )  # doctest: +SKIP
            >>> ctx.sql("SELECT * FROM remote_table").collect()  # doctest: +SKIP
        """
        self.ctx.set_query_planner(planner)

    def with_extensions(
        self, *extensions: SessionComponentsExportable | SessionPlannerExportable
    ) -> SessionContext:
        """Create a new session context with the given extension bundles.

        This is the preferred way to install extension codecs and query
        planners, because it removes the ordering question that installing them
        by hand creates.

        Each argument is called twice, in two phases:

        1. ``__datafusion_session_components__(ctx)`` on every extension, then
           all the returned codecs are installed at once.
        2. ``__datafusion_session_planner__(ctx, fallback)`` on every
           extension, **in argument order**, each handed the planner built so
           far and the context carrying every bundle's codecs. The last
           extension listed ends up outermost.

        An extension implements either hook or both. Return ``None`` from the
        planner hook to contribute no planner; see
        :py:class:`~datafusion.extensions.SessionPlannerExportable`.

        Nothing is written to the session until every hook has returned and
        every component has been validated, so a hook that raises leaves the
        session as it was. Declared functions and optimizer rules install after
        the planner is bound, and are visible on every handle sharing this
        session. A hook that *mutates* the context it is handed — registering a
        table, say — is not rolled back, which is why bundle objects must be
        configuration-only.

        A call that installs optimizer rules rebuilds the session state, which
        drops the session's prepared statements — see
        :ref:`extension_rule_rebuild`.

        Shares its session with this context — see :py:class:`SessionContext`.

        See :ref:`extension_bundles` in the online documentation for why the
        phases are split, how to contribute a bundle's two halves at different
        positions, and a worked Rust implementation.

        Args:
            extensions: Extension bundles to install. Order is irrelevant for
                codecs and significant for planners, which nest in this order
                with the last one outermost. Passing none installs nothing and
                returns a handle on this session, so a caller assembling the
                list at runtime need not special-case it being empty.

        Returns:
            A new context with all extension components installed.

        Raises:
            TypeError: If an argument implements neither hook, if a hook
                returns the wrong type, if a codec is contributed as a bare
                ``PyCapsule`` rather than an object exposing the getter, or if
                a declared function or optimizer rule does not expose its
                capsule getter and is not already a wrapper.
            ValueError: If two codecs claim the same id, if two extensions
                declare a function of one kind under the same name, or if a
                getter returns a capsule of the wrong kind. See
                :py:meth:`with_logical_extension_codec` for how ids are
                assigned.
            RuntimeError: If a getter is present but returns something that is
                not a ``PyCapsule`` at all. The message comes from the importer
                and does not name the bundle, because by then the declaration
                has already been accepted as the right shape.

        Examples:
            The returned handle is a different object sharing one session, and
            an empty call is legal:

            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> derived = ctx.with_extensions()
            >>> derived is ctx
            False
            >>> ctx.from_pydict({"a": [1, 2]}, name="t")  # doctest: +ELLIPSIS
            DataFrame()...
            >>> derived.table_exist("t")
            True
            >>> derived.logical_extension_codec_ids()
            []

            A runnable multi-bundle example, showing what a bundle returns and
            how its codec ids accumulate, is in :ref:`extension_bundles`.

            Real usage. Skipped here (needs a built extension library); run
            verbatim by ``test_with_extensions_docstring_example_still_runs``.

            >>> from my_extension import DistributedEngineExtension  # doctest: +SKIP
            >>> ctx = SessionContext().with_extensions(
            ...     DistributedEngineExtension("scheduler:50050")
            ... )  # doctest: +SKIP
            >>> batches = ctx.sql("SELECT 1 AS n").collect()  # doctest: +SKIP
            >>> batches[0].column(0).to_pylist()  # doctest: +SKIP
            [1]
        """
        # Phase one: collect every bundle's components. Components are bound
        # against this context, not a context derived from it. There is one
        # `Arc<SessionContext>` per session, so a component bound here holds a
        # task-context provider that the returned handle keeps alive.
        logical_codecs, physical_codecs, declared = _collect_contributions(
            extensions, self
        )

        # Writes nothing: the chains belong to the new handle, so a failure
        # above or below leaves this context as it was.
        new = SessionContext.__new__(SessionContext)
        new.ctx = self.ctx._install_extension_codecs(logical_codecs, physical_codecs)

        # Resolve every declared function to the wrapper that registers it, and
        # settle name collisions, while a failure still costs nothing. None of
        # these getters take an argument, so unlike a provider they do not care
        # which handle they are resolved against.
        from datafusion import user_defined as _user_defined  # noqa: PLC0415

        resolved: dict[str, list[Any]] = {
            kind.field: _resolve_declared_functions(
                declared[kind.field],
                getattr(_user_defined, kind.wrapper),
                kind.getter,
                getattr(_user_defined, kind.factory),
                kind.label,
            )
            for kind in _FUNCTION_KINDS
        }
        # Rules accumulate, so there is no name to check and nothing to refuse
        # -- only the capsules to import while failing is still free.
        resolved_rules = _resolve_declared_rules(
            declared["physical_optimizer_rules"],
            new.ctx._resolve_extension_physical_optimizer_rules,
        )

        # Phase two: run the planner hooks and commit, in one call. Each hook
        # runs against `new`, which carries the final chains, so a planner
        # captured there never sees a partial codec set. The hook loop, the
        # ordering of the commit, and the guard that skips the planner rebind
        # for a call that installs nothing all live on the Rust side -- see
        # `_commit_extensions` and docs/source/contributor-guide/
        # ffi-internals.md, under "Why `with_extensions` commits last". A new
        # component field must be resolved above and given its own
        # `_commit_extensions` parameter; the call's arity is what keeps a
        # declared component from being quietly dropped.
        new.ctx._commit_extensions(
            list(extensions),
            new,
            bool(logical_codecs or physical_codecs),
            [function._udf for function in resolved["udfs"]],
            [function._udaf for function in resolved["udafs"]],
            [function._udwf for function in resolved["udwfs"]],
            resolved_rules,
        )
        return new

    def table_provider(self, name: str) -> Table:
        """Return the :py:class:`~datafusion.catalog.Table` for the given table name.

        Args:
            name: Name of the table.

        Returns:
            The table provider.

        Raises:
            KeyError: If the table is not found.

        Examples:
            >>> import pyarrow as pa
            >>> ctx = SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"x": [1, 2]})
            >>> ctx.register_record_batches("my_table", [[batch]])
            >>> tbl = ctx.table_provider("my_table")
            >>> tbl.schema
            x: int64
        """
        from datafusion.catalog import Table  # noqa: PLC0415

        return Table(self.ctx.table_provider(name))

    def read_json(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        schema_infer_max_records: int = 1000,
        file_extension: str = ".json",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a line-delimited JSON data source.

        Args:
            path: Path to the JSON file.
            schema: The data source schema.
            schema_infer_max_records: Maximum number of rows to read from JSON
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            table_partition_cols: Partition columns.
            file_compression_type: File compression type.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read JSON files.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        return DataFrame(
            self.ctx.read_json(
                path,
                schema,
                schema_infer_max_records,
                file_extension,
                table_partition_cols,
                file_compression_type,
            )
        )

    def read_csv(
        self,
        path: str | pathlib.Path | list[str] | list[pathlib.Path],
        schema: pa.Schema | None = None,
        has_header: bool = True,
        delimiter: str = ",",
        schema_infer_max_records: int = DEFAULT_MAX_INFER_SCHEMA,
        file_extension: str = ".csv",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        options: CsvReadOptions | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a CSV data source.

        Args:
            path: Path to the CSV file
            schema: An optional schema representing the CSV files. If None, the
                CSV reader will try to infer it based on data in file.
            has_header: Whether the CSV file have a header. If schema inference
                is run on a file with no headers, default column names are
                created.
            delimiter: An optional column delimiter.
            schema_infer_max_records: Maximum number of rows to read from CSV
                files for schema inference if needed.
            file_extension:  File extension; only files with this extension are
                selected for data input.
            table_partition_cols:  Partition columns.
            file_compression_type:  File compression type.
            options: Set advanced options for CSV reading. This cannot be
                combined with any of the other options in this method.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read CSV files
        """
        if object_store is not None:
            register_path = path[0] if isinstance(path, list) else path
            self._register_object_store_for_path(register_path, object_store)
        if options is not None and (
            schema is not None
            or not has_header
            or delimiter != ","
            or schema_infer_max_records != DEFAULT_MAX_INFER_SCHEMA
            or file_extension != ".csv"
            or table_partition_cols is not None
            or file_compression_type is not None
        ):
            message = (
                "Combining CsvReadOptions parameter with additional options "
                "is not supported. Use CsvReadOptions to set parameters."
            )
            warnings.warn(
                message,
                category=UserWarning,
                stacklevel=2,
            )

        options = (
            options
            if options is not None
            else CsvReadOptions(
                schema=schema,
                has_header=has_header,
                delimiter=delimiter,
                schema_infer_max_records=schema_infer_max_records,
                file_extension=file_extension,
                table_partition_cols=table_partition_cols,
                file_compression_type=file_compression_type,
            )
        )

        return DataFrame(
            self.ctx.read_csv(
                path,
                options.to_inner(),
            )
        )

    def read_parquet(
        self,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        parquet_pruning: bool = True,
        file_extension: str = ".parquet",
        skip_metadata: bool = True,
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a Parquet source into a :py:class:`~datafusion.dataframe.Dataframe`.

        Args:
            path: Path to the Parquet file.
            table_partition_cols: Partition columns.
            parquet_pruning: Whether the parquet reader should use the predicate
                to prune row groups.
            file_extension: File extension; only files with this extension are
                selected for data input.
            skip_metadata: Whether the parquet reader should skip any metadata
                that may be in the file schema. This can help avoid schema
                conflicts due to metadata.
            schema: An optional schema representing the parquet files. If None,
                the parquet reader will try to infer it based on data in the
                file.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
            object_store: A pre-configured object store instance (e.g.
                :py:class:`~datafusion.object_store.AmazonS3`,
                :py:class:`~datafusion.object_store.GoogleCloud`,
                :py:class:`~datafusion.object_store.MicrosoftAzure`) to use
                for accessing the file. When provided, the store is
                automatically registered for the URL scheme and host parsed
                from ``path``, removing the need to call
                :py:meth:`register_object_store` separately. This is
                especially useful in multi-threaded environments where
                setting credentials via ``os.environ`` is not thread-safe.

        Returns:
            DataFrame representation of the read Parquet files

        Examples:
            Read a local Parquet file:

            >>> import datafusion
            >>> ctx = datafusion.SessionContext()
            >>> df = ctx.read_parquet("data.parquet")  # doctest: +SKIP

            Read from S3 with inline credentials (thread-safe):

            >>> from datafusion.object_store import AmazonS3  # doctest: +SKIP
            >>> store = AmazonS3(
            ...     bucket_name="my-bucket",
            ...     region="us-east-1",
            ...     access_key_id="...",
            ...     secret_access_key="...",
            ... )  # doctest: +SKIP
            >>> df = ctx.read_parquet(
            ...     "s3://my-bucket/data.parquet",
            ...     object_store=store,
            ... )  # doctest: +SKIP
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        file_sort_order = self._convert_file_sort_order(file_sort_order)
        return DataFrame(
            self.ctx.read_parquet(
                path,
                table_partition_cols,
                parquet_pruning,
                file_extension,
                skip_metadata,
                schema,
                file_sort_order,
            )
        )

    def read_avro(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_extension: str = ".avro",
        object_store: Any | None = None,
    ) -> DataFrame:
        """Create a :py:class:`DataFrame` for reading Avro data source.

        Args:
            path: Path to the Avro file.
            schema: The data source schema.
            file_partition_cols: Partition columns.
            file_extension: File extension to select.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read Avro file
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if file_partition_cols is None:
            file_partition_cols = []
        file_partition_cols = _convert_table_partition_cols(file_partition_cols)
        return DataFrame(
            self.ctx.read_avro(path, schema, file_partition_cols, file_extension)
        )

    def read_arrow(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".arrow",
        file_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Create a :py:class:`DataFrame` for reading an Arrow IPC data source.

        Args:
            path: Path to the Arrow IPC file.
            schema: The data source schema.
            file_extension: File extension to select.
            file_partition_cols: Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read Arrow IPC file.

        Examples:
            >>> import tempfile, os
            >>> ctx = dfn.SessionContext()
            >>> table = pa.table({"a": [1, 2, 3]})
            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path)
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]

            Provide an explicit ``schema`` to override schema inference:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path, schema=pa.schema([("a", pa.int64())]))
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]

            Use ``file_extension`` to read files with a non-default extension:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.ipc")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path, file_extension=".ipc")
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if file_partition_cols is None:
            file_partition_cols = []
        file_partition_cols = _convert_table_partition_cols(file_partition_cols)
        return DataFrame(
            self.ctx.read_arrow(path, schema, file_extension, file_partition_cols)
        )

    def read_empty(self) -> DataFrame:
        """Create an empty :py:class:`DataFrame` with no columns or rows.

        See Also:
            This is an alias for :meth:`empty_table`.
        """
        return self.empty_table()

    def read_table(
        self, table: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset
    ) -> DataFrame:
        """Creates a :py:class:`~datafusion.dataframe.DataFrame` from a table."""
        return DataFrame(self.ctx.read_table(table))

    def execute(self, plan: ExecutionPlan, partition: int) -> RecordBatchStream:
        """Execute a single partition of ``plan`` and stream its batches.

        Args:
            plan: The physical plan to execute.
            partition: Index of the partition to execute, in
                ``range(plan.partition_count)``.

        Returns:
            A stream over the record batches that partition produces.

        Raises:
            ValueError: If ``partition`` is not a valid index for ``plan``.
            OverflowError: If ``partition`` is negative, or too large to fit a
                platform-sized unsigned integer.

        Example usage:

        >>> import pyarrow as pa
        >>> from datafusion import SessionContext
        >>> ctx = SessionContext()
        >>> ctx.register_record_batches(
        ...     "t", [[pa.record_batch({"a": [1, 2]})], [pa.record_batch({"a": [3]})]]
        ... )
        >>> plan = ctx.sql("select a from t").execution_plan()
        >>> plan.partition_count
        2
        >>> sum(
        ...     batch.to_pyarrow().num_rows
        ...     for p in range(plan.partition_count)
        ...     for batch in ctx.execute(plan, p)
        ... )
        3
        """
        return RecordBatchStream(self.ctx.execute(plan._raw_plan, partition))

    @staticmethod
    def _convert_file_sort_order(
        file_sort_order: Sequence[Sequence[SortKey]] | None,
    ) -> list[list[expr_internal.SortExpr]] | None:
        """Convert nested ``SortKey`` sequences into raw sort expressions.

        Each ``SortKey`` can be a column name string, an ``Expr``, or a
        ``SortExpr`` and will be converted using
        :func:`datafusion.expr.sort_list_to_raw_sort_list`.
        """
        # Convert each ``SortKey`` in the provided sort order to the low-level
        # representation expected by the Rust bindings.
        return (
            [sort_list_to_raw_sort_list(f) for f in file_sort_order]
            if file_sort_order is not None
            else None
        )

    @staticmethod
    def _convert_table_partition_cols(
        table_partition_cols: list[tuple[str, str | pa.DataType]],
    ) -> list[tuple[str, pa.DataType]]:
        warn = False
        converted_table_partition_cols = []

        for col, data_type in table_partition_cols:
            if isinstance(data_type, str):
                warn = True
                if data_type == "string":
                    converted_data_type = pa.string()
                elif data_type == "int":
                    converted_data_type = pa.int32()
                else:
                    message = (
                        f"Unsupported literal data type '{data_type}' for partition "
                        "column. Supported types are 'string' and 'int'"
                    )
                    raise ValueError(message)
            else:
                converted_data_type = data_type

            converted_table_partition_cols.append((col, converted_data_type))

        if warn:
            message = (
                "using literals for table_partition_cols data types is deprecated,"
                "use pyarrow types instead"
            )
            warnings.warn(
                message,
                category=DeprecationWarning,
                stacklevel=2,
            )

        return converted_table_partition_cols

    def __datafusion_task_context_provider__(self) -> Any:
        """Access the PyCapsule FFI_TaskContextProvider."""
        return self.ctx.__datafusion_task_context_provider__()

    @property
    def __datafusion_codec_id__(self) -> str:
        """Identity this context carries when installed as an extension codec.

        A context can be installed on another session as an extension codec,
        which tags the payloads it writes with this string. It is unique per
        session, so two contexts can be installed on one session and a plan
        written through one will not be decoded by the other.

        Contexts derived from the same session report the same id, so only one
        of them can be installed on a given session. That is the intended
        answer: they are one session — see :py:class:`SessionContext` — so
        their payloads would be indistinguishable on decode.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> ctx.__datafusion_codec_id__.startswith("session:")
            True
            >>> ctx.__datafusion_codec_id__ == SessionContext().__datafusion_codec_id__
            False
        """
        return self.ctx.__datafusion_codec_id__

    def __datafusion_logical_extension_codec__(self, session: Any = None) -> Any:
        """Access the PyCapsule FFI_LogicalExtensionCodec.

        ``session`` is accepted so a context satisfies the same protocol an
        extension library implements, where the argument is how the library
        reaches the host's codec. A context already carries one, so the
        argument is ignored. See
        :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`
        for what an extension library does with it.

        Args:
            session: Accepted and ignored.

        Returns:
            A ``datafusion_logical_extension_codec`` PyCapsule.

        Examples:
            >>> from datafusion import SessionContext
            >>> type(SessionContext().__datafusion_logical_extension_codec__()).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_logical_extension_codec__(session)

    def __datafusion_query_planner__(self, session: Any = None) -> Any:
        """Access the ``FFI_QueryPlanner`` PyCapsule for the current planner.

        This is how you capture the planner a session already has in order to
        wrap it. Capture it *before* installing the new one, since
        :py:meth:`set_query_planner` replaces rather than layers.

        Args:
            session: Accepted and ignored. See
                :meth:`__datafusion_logical_extension_codec__`.

        Returns:
            A ``datafusion_query_planner`` PyCapsule wrapping the session's
            current planner, exported for a foreign planner to delegate to.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> fallback = ctx.__datafusion_query_planner__()
            >>> type(fallback).__name__
            'PyCapsule'

            Both spellings work, since the argument is ignored:

            >>> type(ctx.__datafusion_query_planner__(ctx)).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_query_planner__(session)

    def with_logical_extension_codec(
        self,
        codec: LogicalExtensionCodecExportable | _PyCapsule,
        codec_id: str | None = None,
    ) -> SessionContext:
        """Create a new session context with an additional logical codec.

        Only FFI codecs are supported. Pass any object implementing
        ``__datafusion_logical_extension_codec__`` (see
        :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`).

        Codecs compose: each call appends the codec rather than replacing
        codecs installed earlier, so one session can carry codecs from several
        independent libraries and the order they are installed in does not
        affect decoding.

        A serialized plan records which codec wrote each payload, as a short id
        taken from the codec's class.

        Shares its session with this context — see :py:class:`SessionContext`.

        See :ref:`extension_codec_ids` in the online documentation for how ids
        are assigned and what an extension codec has to implement, and
        :py:meth:`with_extensions` for installing a library's codecs and planner
        together.

        Args:
            codec: Object implementing ``__datafusion_logical_extension_codec__``
                (see
                :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`),
                or a raw ``datafusion_logical_extension_codec`` PyCapsule.
            codec_id: Overrides the id the codec's payloads are tagged with.
                Normally unnecessary. Pass it when installing two instances of
                one class, which otherwise claim the same id, and when
                installing a bare ``PyCapsule``: a capsule has no class to take
                an id from, so it is given a random ``anon:`` id that differs on
                every install, and plans it encodes can never be decoded
                elsewhere.

        Returns:
            A new context carrying this codec in addition to any already
            installed.

        Raises:
            ValueError: If the resolved id is already installed on this session.

        Examples:
            A context exports its own codec, which stands in here for a real
            library's:

            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> capsule = host.__datafusion_logical_extension_codec__()
            >>> ctx = SessionContext().with_logical_extension_codec(
            ...     capsule, codec_id="my_library.Codec"
            ... )
            >>> ctx.logical_extension_codec_ids()
            ['my_library.Codec']

            Without ``codec_id`` a bare capsule gets an anonymous id, which is
            fine only if its plans never leave this session:

            >>> ctx = SessionContext().with_logical_extension_codec(capsule)
            >>> ctx.logical_extension_codec_ids()[0].startswith("anon:")
            True
        """
        new_internal = self.ctx.with_logical_extension_codec(codec, codec_id)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new

    def logical_extension_codec_ids(self) -> list[str]:
        """List the logical extension codecs installed on this session.

        Returns the identity of each installed codec, in install order. Those
        identities are what encoding stamps onto a payload and what decoding
        dispatches on, so this is how to check which library owns a plan and
        whether a session is able to decode one.

        DataFusion's own default codec is not listed. It handles whatever no
        installed codec claims, and it carries no identity to list.

        Returns:
            The installed codec ids, in install order. Empty if none are
            installed.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> host.logical_extension_codec_ids()
            []
            >>> capsule = host.__datafusion_logical_extension_codec__()
            >>> ctx = SessionContext().with_logical_extension_codec(
            ...     capsule, codec_id="my_library.Codec"
            ... )
            >>> ctx.logical_extension_codec_ids()
            ['my_library.Codec']
        """
        return self.ctx.logical_extension_codec_ids()

    def __datafusion_physical_extension_codec__(self, session: Any = None) -> Any:
        """Access the PyCapsule FFI_PhysicalExtensionCodec.

        See :meth:`__datafusion_logical_extension_codec__` for ``session``.

        Args:
            session: Accepted and ignored.

        Returns:
            A ``datafusion_physical_extension_codec`` PyCapsule.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> type(ctx.__datafusion_physical_extension_codec__()).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_physical_extension_codec__(session)

    def physical_extension_codec_ids(self) -> list[str]:
        """List the physical extension codecs installed on this session.

        See :py:meth:`logical_extension_codec_ids`.

        Returns:
            The installed codec ids, in install order. Empty if none are
            installed.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> host.physical_extension_codec_ids()
            []
            >>> capsule = host.__datafusion_physical_extension_codec__()
            >>> ctx = SessionContext().with_physical_extension_codec(
            ...     capsule, codec_id="my_library.PhysicalCodec"
            ... )
            >>> ctx.physical_extension_codec_ids()
            ['my_library.PhysicalCodec']
        """
        return self.ctx.physical_extension_codec_ids()

    def with_physical_extension_codec(
        self,
        codec: PhysicalExtensionCodecExportable | _PyCapsule,
        codec_id: str | None = None,
    ) -> SessionContext:
        """Create a new session context with an additional physical codec.

        Only FFI codecs are supported. Pass any object implementing
        ``__datafusion_physical_extension_codec__`` (see
        :py:class:`~datafusion.user_defined.PhysicalExtensionCodecExportable`).

        Composes and assigns an id exactly as
        :py:meth:`with_logical_extension_codec` does, including when to pass
        ``codec_id`` and what the returned context shares. See that method.

        Args:
            codec: As :py:meth:`with_logical_extension_codec`, for the physical
                getter.
            codec_id: As :py:meth:`with_logical_extension_codec`.

        Returns:
            A new context carrying this codec in addition to any already
            installed.

        Raises:
            ValueError: If the resolved id is already installed on this session.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> capsule = host.__datafusion_physical_extension_codec__()
            >>> ctx = SessionContext().with_physical_extension_codec(
            ...     capsule, codec_id="my_library.PhysicalCodec"
            ... )
            >>> ctx.physical_extension_codec_ids()
            ['my_library.PhysicalCodec']
        """
        new_internal = self.ctx.with_physical_extension_codec(codec, codec_id)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new

    def with_python_udf_inlining(self, *, enabled: bool) -> SessionContext:
        """Control whether Python UDFs are embedded in serialized expressions.

        With ``enabled=True``, serialized expressions carry the Python
        code for any scalar, aggregate, or window UDFs they reference.
        The receiver rebuilds the UDFs from those bytes and does not
        need to register them first.

        With ``enabled=False``, serialized expressions store only the
        UDF names. This has two uses:

        * **Cross-language portability.** The bytes can be decoded by a
          non-Python receiver, which must already have UDFs registered
          under matching names.
        * **Safer deserialization.** :meth:`Expr.from_bytes` will refuse
          to rebuild Python UDFs rather than call ``cloudpickle.loads``
          on untrusted input.

        The setting affects :meth:`Expr.to_bytes` and
        :meth:`Expr.from_bytes` whenever this session is passed as the
        ``ctx`` argument. :func:`pickle.dumps` and :func:`pickle.loads`
        do not pass a context, so to apply the setting through pickle,
        register this session with
        :func:`datafusion.ipc.set_sender_ctx` on the sender and
        :func:`datafusion.ipc.set_worker_ctx` on the receiver.

        .. warning:: Security
            This setting narrows only :meth:`Expr.from_bytes`. Calling
            :func:`pickle.loads` on untrusted bytes remains unsafe
            regardless of the toggle.

        Shares its session with this context — see
        :py:class:`SessionContext`. The original context's own codec
        settings are unchanged.

        Args:
            enabled: Whether to embed Python UDFs in serialized
                expressions. Keyword-only and required, so callers must
                pick a mode explicitly. Fresh sessions behave as
                ``enabled=True`` until this method overrides the toggle.

        Returns:
            A new :class:`SessionContext` with the toggle applied.

        Examples:
            >>> import pyarrow as pa
            >>> from datafusion import SessionContext, Expr, col, udf
            >>> ctx = SessionContext()
            >>> identity = udf(lambda a: a, [pa.int64()], pa.int64(),
            ...                volatility="immutable", name="identity_demo")
            >>> ctx.register_udf(identity)
            >>> blob = identity(col("x")).to_bytes(ctx)
            >>> strict = SessionContext().with_python_udf_inlining(enabled=False)
            >>> try:
            ...     Expr.from_bytes(blob, strict)
            ... except Exception as e:
            ...     print("Refusing to deserialize" in str(e))
            True
        """
        new_internal = self.ctx.with_python_udf_inlining(enabled)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new
