Skip to content

LogicalPlan::get_parameter_types fails to return all placeholders #13678

@davisp

Description

@davisp

Describe the bug

Calling LogicalPlan::get_parameter_types() does not return the place holder from SELECT $1;.

To Reproduce

The assertion triggers because no parameters are returned.

use datafusion::error::Result;
use datafusion::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    let ctx = SessionContext::new();
    let plan = ctx.state().create_logical_plan("SELECT $1;").await?;
    let params = plan.get_parameter_types()?;
    assert_eq!(params.len(), 1);
    Ok(())
}

Expected behavior

All placeholders are returned.

Additional context

There appears to be a builtin assumption that get_parameter_types only returns placeholders that have a resolved type while filtering out anything with a None data_type:

match (prev, data_type) {
(Some(Some(prev)), Some(dt)) => {
if prev != dt {
plan_err!("Conflicting types for {id}")?;
}
}
(_, Some(dt)) => {
param_types.insert(id.clone(), Some(dt.clone()));
}
_ => {}
}
}

I can't decide if that's a valid assumption or was just a left over from when things were relying on Placeholders to always have a resolved datatype. Given that the function signature is HashMap<String, Option<DataType>> but values are guaranteed to always be Some, I'm just plain confused.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions