Reports the repr schema of the relation. This method determines the type through recursive traversal of the relation expression, drawing from the types of base collections. As such, this is not an especially cheap method, and should be used judiciously. The relation type is computed incrementally with a recursive post-order traversal, that accumulates the input types for the relations yet to be
(&self)
| 346 | /// traversal, that accumulates the input types for the relations yet to be |
| 347 | /// visited in `type_stack`. |
| 348 | pub fn typ(&self) -> ReprRelationType { |
| 349 | let mut type_stack = Vec::new(); |
| 350 | self.visit_pre_post( |
| 351 | &mut |e: &MirRelationExpr| -> Option<Vec<&MirRelationExpr>> { |
| 352 | match &e { |
| 353 | MirRelationExpr::Let { body, .. } => Some(vec![&*body]), |
| 354 | MirRelationExpr::LetRec { body, .. } => Some(vec![&*body]), |
| 355 | _ => None, |
| 356 | } |
| 357 | }, |
| 358 | &mut |e: &MirRelationExpr| { |
| 359 | match e { |
| 360 | MirRelationExpr::Let { .. } => { |
| 361 | let body_typ = type_stack.pop().unwrap(); |
| 362 | // Insert a dummy relation type for the value, since `typ_with_input_types` |
| 363 | // won't look at it, but expects the relation type of the body to be second. |
| 364 | type_stack.push(ReprRelationType::empty()); |
| 365 | type_stack.push(body_typ); |
| 366 | } |
| 367 | MirRelationExpr::LetRec { values, .. } => { |
| 368 | let body_typ = type_stack.pop().unwrap(); |
| 369 | type_stack.extend( |
| 370 | std::iter::repeat(ReprRelationType::empty()).take(values.len()), |
| 371 | ); |
| 372 | // Insert dummy relation types for the values, since `typ_with_input_types` |
| 373 | // won't look at them, but expects the relation type of the body to be last. |
| 374 | type_stack.push(body_typ); |
| 375 | } |
| 376 | _ => {} |
| 377 | } |
| 378 | let num_inputs = e.num_inputs(); |
| 379 | let relation_type = |
| 380 | e.typ_with_input_types(&type_stack[type_stack.len() - num_inputs..]); |
| 381 | type_stack.truncate(type_stack.len() - num_inputs); |
| 382 | type_stack.push(relation_type); |
| 383 | }, |
| 384 | ); |
| 385 | assert_eq!(type_stack.len(), 1); |
| 386 | type_stack.pop().unwrap() |
| 387 | } |
| 388 | |
| 389 | /// Reports the repr schema of the relation given the repr schema of the input relations. |
| 390 | pub fn typ_with_input_types(&self, input_types: &[ReprRelationType]) -> ReprRelationType { |
no test coverage detected