Skip to content

Expand Session trait to parity with SessionState #23678

Description

@timsaucer

Is your feature request related to a problem or challenge?

At a high level we are trying to expand our FFI crate to support both datafusion-python and datafusion-java with more extension points. The problem we run into when using these other languages with multiple libraries is that we cannot perform any kind of downcasting of a &dyn Session into the underlying &Session. There is a discussion of why this is the case on the datafusion-python online documentation.

What we want to do is to expose more of the functions currently in SessionState to be usable by anyone with access to a &dyn Session.

One use case: Users wish to be able to access the CatalogListProvider so that a table function could create a new view of an existing table. We cannot currently do this with &Session because the catalog_list() function does not exist on it.

Second use case: Users wish to create a query planner to replace the build in query planner. The problem with this is that the method within QueryPlanner, create_physical_plan() takes a &SessionState parameter. For us to be able to expose a FFI_QueryPlanner we need this method to take &dyn Session, which in turn needs PhysicalPlanner to have a similar change. If we want to create method to expose or set a query planner on the Session we need to resolve the fact that these traits are defined in datafusion-core so not accessible to Session.

Describe the solution you'd like

I would like to reorganize our trait definitions. Specifically it seems like we need to either hoist these trait definitions into either datafusion-session or the datafusion-expr crates. Before doing any work, I think we should review the dependency graph and consider if we should have some thin crates that only expose surface API surfaces or not. On the one hand, that could be cleaner than doing something along the lines of adding QueryPlanner, PhysicalPlanner, CatalogProviderList, TableProvider, etc into either datafusion-session or datafusion-expr crates. The down side of adding additional crates is that we're now adding even more crates to our already pretty large dependency graph.

I think the first task should be to review and propose a solution for where the trait definitions should sit.

Describe alternatives you've considered

There is another path where we use type erasure and then downcasting so that we don't have dependency graph problems. Personally I find this to be a hacky way to get around the dependency issue.

Additional context

Related issues:

Activity

  1. timsaucer commented on Jul 17, 2026

    @timsaucer
    MemberAuthor

    FYI @alamb who was asking for this. Please let me know if more context would be helpful.

  2. timsaucer commented on Jul 19, 2026

    @timsaucer
    MemberAuthor

    I've been working with a few agents this morning and I've settled on a plan that I think is reasonable:

    1. Catalog contract extraction

    • Move the catalog/provider trait closure into datafusion-session.
    • Reexport it from datafusion-catalog.
    • Add Session::catalog_list (fn catalog_list(&self) -> Arc<dyn CatalogProviderList>;)
    • Implement it for SessionState.
    • Preserve existing public import paths.

    This can be reviewed independently from planner behavior.

    2. Physical optimizer interface extraction

    • Move PhysicalOptimizerRule and PhysicalOptimizerContext definitions.
    • Reexport them from datafusion-physical-optimizer.
    • Keep all optimizer implementations where they are.
    • Establish the minimal planning capabilities required from Session.

    3. Planner contract extraction and signature conversion

    After #23649 merges:

    • Move QueryPlanner, PhysicalPlanner, and ExtensionPlanner definitions.
    • Change every session argument to &dyn Session.
    • Add Session::query_planner.
    • Add the logical-optimization capability needed for nested plans.
    • Update DefaultQueryPlanner and DefaultPhysicalPlanner.
    • Keep default implementations in core.

    4. Prove implementation independence

    Add a test session implementation that is deliberately not SessionState and cannot be downcast to it. Demonstrate that it can:

    • expose and use a catalog;
    • expose a custom query planner;
    • run the planner through &dyn Session;
    • plan extension nodes and physical expressions without downcasting.

    This is more valuable than tests that only substitute &dyn Session while still passing a SessionState.

    5. FFI work as a subsequent change

    Once the Rust contracts settle:

    • extend the FFI session wrapper with catalog and query-planner access;
    • add query/physical planner wrappers;
    • test across the actual cdylib boundary;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions