-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
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:
datafusion/datafusion/expr/src/logical_plan/plan.rs
Lines 1485 to 1496 in fc70323
| 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.