Reports the column types of the relation given the column types of the input relations. `input_types` is required to contain the column types for the input relations of the current relation in the same order as they are visited by `try_visit_children` method, even though not all may be used for computing the schema of the current relation. For example, `Let` expects two input types, one for the v
(
&self,
mut input_types: I,
)
| 423 | /// It is meant to be used during post-order traversals to compute column types |
| 424 | /// incrementally. |
| 425 | pub fn try_col_with_input_cols<'a, I>( |
| 426 | &self, |
| 427 | mut input_types: I, |
| 428 | ) -> Result<Vec<ReprColumnType>, String> |
| 429 | where |
| 430 | I: Iterator<Item = &'a Vec<ReprColumnType>>, |
| 431 | { |
| 432 | use MirRelationExpr::*; |
| 433 | |
| 434 | let col_types = match self { |
| 435 | Constant { rows, typ } => { |
| 436 | let mut col_types = typ.column_types.clone(); |
| 437 | let mut seen_null = vec![false; typ.arity()]; |
| 438 | if let Ok(rows) = rows { |
| 439 | for (row, _diff) in rows { |
| 440 | for (datum, i) in row.iter().zip_eq(0..typ.arity()) { |
| 441 | if datum.is_null() { |
| 442 | seen_null[i] = true; |
| 443 | } |
| 444 | } |
| 445 | } |
| 446 | } |
| 447 | for (&seen_null, i) in seen_null.iter().zip_eq(0..typ.arity()) { |
| 448 | if !seen_null { |
| 449 | col_types[i].nullable = false; |
| 450 | } else { |
| 451 | assert!(col_types[i].nullable); |
| 452 | } |
| 453 | } |
| 454 | col_types |
| 455 | } |
| 456 | Get { typ, .. } => typ.column_types.clone(), |
| 457 | Project { outputs, .. } => { |
| 458 | let input = input_types.next().unwrap(); |
| 459 | outputs.iter().map(|&i| input[i].clone()).collect() |
| 460 | } |
| 461 | Map { scalars, .. } => { |
| 462 | let mut result = input_types.next().unwrap().clone(); |
| 463 | for scalar in scalars.iter() { |
| 464 | result.push(scalar.typ(&result)) |
| 465 | } |
| 466 | result |
| 467 | } |
| 468 | FlatMap { func, .. } => { |
| 469 | let mut result = input_types.next().unwrap().clone(); |
| 470 | result.extend( |
| 471 | func.output_sql_type() |
| 472 | .column_types |
| 473 | .iter() |
| 474 | .map(ReprColumnType::from), |
| 475 | ); |
| 476 | result |
| 477 | } |
| 478 | Filter { predicates, .. } => { |
| 479 | let mut result = input_types.next().unwrap().clone(); |
| 480 | |
| 481 | // Set as nonnull any columns where null values would cause |
| 482 | // any predicate to evaluate to null. |