Normalize column references to a sorted, deduplicated options list of column names.
(
cols: Vec<UnresolvedItemName>,
reference_resolver: &SourceReferenceResolver,
tables: &[RequestedSourceExport<MySqlTableDesc>],
option_name: &str,
)
| 252 | |
| 253 | /// Normalize column references to a sorted, deduplicated options list of column names. |
| 254 | pub(super) fn normalize_column_refs( |
| 255 | cols: Vec<UnresolvedItemName>, |
| 256 | reference_resolver: &SourceReferenceResolver, |
| 257 | tables: &[RequestedSourceExport<MySqlTableDesc>], |
| 258 | option_name: &str, |
| 259 | ) -> Result<Vec<WithOptionValue<Aug>>, MySqlSourcePurificationError> { |
| 260 | let (seq, unknown): (Vec<_>, Vec<_>) = cols.into_iter().partition(|name| { |
| 261 | let (column_name, qual) = name.0.split_last().expect("non-empty"); |
| 262 | match reference_resolver.resolve_idx(qual) { |
| 263 | // TODO: this needs to also introduce the maximum qualification on |
| 264 | // the columns, i.e. ensure they have the schema name. |
| 265 | Ok(idx) => tables[idx] |
| 266 | .meta |
| 267 | .columns |
| 268 | .iter() |
| 269 | .any(|n| &n.name == column_name.as_str()), |
| 270 | Err(_) => false, |
| 271 | } |
| 272 | }); |
| 273 | |
| 274 | if !unknown.is_empty() { |
| 275 | return Err(MySqlSourcePurificationError::DanglingColumns { |
| 276 | option_name: option_name.to_string(), |
| 277 | items: unknown, |
| 278 | }); |
| 279 | } |
| 280 | |
| 281 | let mut seq: Vec<_> = seq |
| 282 | .into_iter() |
| 283 | .map(WithOptionValue::UnresolvedItemName) |
| 284 | .collect(); |
| 285 | seq.sort(); |
| 286 | seq.dedup(); |
| 287 | Ok(seq) |
| 288 | } |
| 289 | |
| 290 | pub(super) async fn validate_requested_references_privileges( |
| 291 | requested_external_references: impl Iterator<Item = &UnresolvedItemName>, |
no test coverage detected