diff --git a/query-projector/src/lib.rs b/query-projector/src/lib.rs index 9eb32622..10737bb1 100644 --- a/query-projector/src/lib.rs +++ b/query-projector/src/lib.rs @@ -371,12 +371,15 @@ fn candidate_column(cc: &ConjoiningClauses, var: &Variable) -> Result<(ColumnOrE }) } -fn candidate_type_column(cc: &ConjoiningClauses, var: &Variable) -> (ColumnOrExpression, Name) { - let extracted_alias = cc.extracted_types - .get(var) - .expect("Every variable has a known type or an extracted type"); - let type_name = VariableColumn::VariableTypeTag(var.clone()).column_name(); - (ColumnOrExpression::Column(extracted_alias.clone()), type_name) +fn candidate_type_column(cc: &ConjoiningClauses, var: &Variable) -> Result<(ColumnOrExpression, Name)> { + cc.extracted_types + .get(var) + .cloned() + .map(|alias| { + let type_name = VariableColumn::VariableTypeTag(var.clone()).column_name(); + (ColumnOrExpression::Column(alias), type_name) + }) + .ok_or_else(|| ErrorKind::UnboundVariable(var.name()).into()) } /// Return the projected column -- that is, a value or SQL column and an associated name -- for a @@ -659,7 +662,7 @@ fn project_elements<'a, I: IntoIterator>( i += 2; // We used two SQL columns. // Also project the type from the SQL query. - let (type_column, type_name) = candidate_type_column(&query.cc, &var); + let (type_column, type_name) = candidate_type_column(&query.cc, &var)?; inner_projection.push(ProjectedColumn(type_column, type_name.clone())); outer_projection.push(Either::Left(type_name)); } @@ -694,7 +697,7 @@ fn project_elements<'a, I: IntoIterator>( inner_projection.push(projected_column); if query.cc.known_type_set(&simple.var).unique_type_tag().is_none() { // Also project the type from the SQL query. - let (type_column, type_name) = candidate_type_column(&query.cc, &simple.var); + let (type_column, type_name) = candidate_type_column(&query.cc, &simple.var)?; inner_projection.push(ProjectedColumn(type_column, type_name.clone())); } } @@ -755,7 +758,7 @@ fn project_elements<'a, I: IntoIterator>( // Single type implies single type tag, and is cheaper, so we check that first. let types = query.cc.known_type_set(&var); if !types.has_unique_type_tag() { - let (type_column, type_name) = candidate_type_column(&query.cc, &var); + let (type_column, type_name) = candidate_type_column(&query.cc, &var)?; if !already_inner { inner_projection.push(ProjectedColumn(type_column, type_name.clone())); } @@ -836,7 +839,7 @@ fn project_elements<'a, I: IntoIterator>( if type_set.unique_type_tag().is_none() { // Also project the type from the SQL query. - let (type_column, type_name) = candidate_type_column(&query.cc, &var); + let (type_column, type_name) = candidate_type_column(&query.cc, &var)?; inner_projection.push(ProjectedColumn(type_column, type_name.clone())); } } diff --git a/query/src/lib.rs b/query/src/lib.rs index 249158dc..4ce03070 100644 --- a/query/src/lib.rs +++ b/query/src/lib.rs @@ -988,10 +988,11 @@ impl OrJoin { let m = self.collect_mentioned_variables(); self.mentioned_vars = Some(m); } + if let Some(ref mentioned) = self.mentioned_vars { mentioned } else { - panic!() + unreachable!() } } }