Returns aliases to make field names unique. Returns a vector of optional aliases, one per input field. `None` means keep the original name, `Some(alias)` means rename to the alias to ensure uniqueness. Used when creating [`SubqueryAlias`] or similar operations that strip table qualifiers but need to maintain unique column names. # Example Input fields: `[a, a, b, b, a, a:1]` ([`DFSchema`] valid
(fields: &Fields)
| 1604 | /// Input fields: `[a, a, b, b, a, a:1]` ([`DFSchema`] valid when duplicate fields have different qualifiers) |
| 1605 | /// Returns: `[None, Some("a:1"), None, Some("b:1"), Some("a:2"), Some("a:1:1")]` |
| 1606 | pub fn unique_field_aliases(fields: &Fields) -> Vec<Option<String>> { |
| 1607 | // Some field names might already come to this function with the count (number of times it appeared) |
| 1608 | // as a suffix e.g. id:1, so there's still a chance of name collisions, for example, |
| 1609 | // if these three fields passed to this function: "col:1", "col" and "col", the function |
| 1610 | // would rename them to -> col:1, col, col:1 causing a posterior error when building the DFSchema. |
| 1611 | // That's why we need the `seen` set, so the fields are always unique. |
| 1612 | |
| 1613 | // Tracks a mapping between a field name and the number of appearances of that field. |
| 1614 | let mut name_map = HashMap::<&str, usize>::new(); |
| 1615 | // Tracks all the fields and aliases that were previously seen. |
| 1616 | let mut seen = HashSet::<Cow<String>>::new(); |
| 1617 | |
| 1618 | fields |
| 1619 | .iter() |
| 1620 | .map(|field| { |
| 1621 | let original_name = field.name(); |
| 1622 | let mut name = Cow::Borrowed(original_name); |
| 1623 | |
| 1624 | let count = name_map.entry(original_name).or_insert(0); |
| 1625 | |
| 1626 | // Loop until we find a name that hasn't been used. |
| 1627 | while seen.contains(&name) { |
| 1628 | *count += 1; |
| 1629 | name = Cow::Owned(format!("{original_name}:{count}")); |
| 1630 | } |
| 1631 | |
| 1632 | seen.insert(name.clone()); |
| 1633 | |
| 1634 | match name { |
| 1635 | Cow::Borrowed(_) => None, |
| 1636 | Cow::Owned(alias) => Some(alias), |
| 1637 | } |
| 1638 | }) |
| 1639 | .collect() |
| 1640 | } |
| 1641 | |
| 1642 | fn mark_field(schema: &DFSchema) -> (Option<TableReference>, Arc<Field>) { |
| 1643 | let mut table_references = schema |