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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions