Skip to content

[substrait] Add Placeholder ↔ DynamicParameter support in producer and consumer #20971

@bvolpato

Description

@bvolpato

Describe the bug

The Substrait producer and consumer do not support DataFusion's Expr::Placeholder (bind parameters like $1, $name). Both directions return not_impl_err!:

Producer (producer/expr/mod.rs:145):

Expr::Placeholder(expr) => not_impl_err!("Cannot convert {expr:?} to Substrait"),

Consumer (substrait_consumer.rs:367-373):

async fn consume_dynamic_parameter(
    &self,
    _expr: &DynamicParameter,
    _input_schema: &DFSchema,
) -> datafusion::common::Result<Expr> {
    not_impl_err!("Dynamic Parameter expression not supported")
}

To Reproduce

Any query involving bind parameters (e.g. prepared statements) cannot be serialized to or deserialized from Substrait:

// Producer: fails
let expr = Expr::Placeholder(Placeholder::new_with_field("$1".into(), Some(Arc::new(Field::new("$1", DataType::Int32, false)))));
// Cannot convert to Substrait

// Consumer: fails
// A Substrait plan containing DynamicParameter cannot be consumed

Expected behavior

The mapping between DataFusion Placeholder and Substrait DynamicParameter should work in both directions:

DataFusion Substrait
Placeholder.id ("$1") DynamicParameter.parameter_reference (extracted index)
Placeholder.field (type info) DynamicParameter.type

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions