Walk the logical plan, find any `Placeholder` tokens, and return a map of their IDs and FieldRefs
(
&self,
)
| 1620 | |
| 1621 | /// Walk the logical plan, find any `Placeholder` tokens, and return a map of their IDs and FieldRefs |
| 1622 | pub fn get_parameter_fields( |
| 1623 | &self, |
| 1624 | ) -> Result<HashMap<String, Option<FieldRef>>, DataFusionError> { |
| 1625 | let mut param_types: HashMap<String, Option<FieldRef>> = HashMap::new(); |
| 1626 | |
| 1627 | self.apply_with_subqueries(|plan| { |
| 1628 | plan.apply_expressions(|expr| { |
| 1629 | expr.apply(|expr| { |
| 1630 | if let Expr::Placeholder(Placeholder { id, field }) = expr { |
| 1631 | let prev = param_types.get(id); |
| 1632 | match (prev, field) { |
| 1633 | (Some(Some(prev)), Some(field)) => { |
| 1634 | check_metadata_with_storage_equal( |
| 1635 | (field.data_type(), Some(field.metadata())), |
| 1636 | (prev.data_type(), Some(prev.metadata())), |
| 1637 | "parameter", |
| 1638 | &format!(": Conflicting types for id {id}"), |
| 1639 | )?; |
| 1640 | } |
| 1641 | (_, Some(field)) => { |
| 1642 | param_types.insert(id.clone(), Some(Arc::clone(field))); |
| 1643 | } |
| 1644 | _ => { |
| 1645 | param_types.insert(id.clone(), None); |
| 1646 | } |
| 1647 | } |
| 1648 | } |
| 1649 | Ok(TreeNodeRecursion::Continue) |
| 1650 | }) |
| 1651 | }) |
| 1652 | }) |
| 1653 | .map(|_| param_types) |
| 1654 | } |
| 1655 | |
| 1656 | // ------------ |
| 1657 | // Various implementations for printing out LogicalPlans |