diff --git a/crates/core/src/vm.rs b/crates/core/src/vm.rs index de907834a9c..a4b5611508a 100644 --- a/crates/core/src/vm.rs +++ b/crates/core/src/vm.rs @@ -112,16 +112,16 @@ fn join_inner<'a>( rhs, header, move |row| { - let f = row.get(&key_lhs, &key_lhs_header); + let f = row.get(&key_lhs, &key_lhs_header)?; Ok(f.into()) }, move |row| { - let f = row.get(&key_rhs, &key_rhs_header); + let f = row.get(&key_rhs, &key_rhs_header)?; Ok(f.into()) }, move |l, r| { - let l = l.get(&col_lhs, &col_lhs_header); - let r = r.get(&col_rhs, &col_rhs_header); + let l = l.get(&col_lhs, &col_lhs_header)?; + let r = r.get(&col_rhs, &col_rhs_header)?; Ok(l == r) }, move |l, r| { diff --git a/crates/lib/src/error.rs b/crates/lib/src/error.rs index 938d52645ce..8bae167b8c8 100644 --- a/crates/lib/src/error.rs +++ b/crates/lib/src/error.rs @@ -120,6 +120,8 @@ pub enum AuthError { pub enum RelationError { #[error("Field `{1}` not found. Must be one of {0}")] FieldNotFound(Header, FieldName), + #[error("Field `{1}` not found at position {0}")] + FieldNotFoundAtPos(usize, FieldName), #[error("Field `{0}` fail to infer the type: {1}")] TypeInference(FieldName, TypeError), #[error("Field declaration only support `table.field` or `field`. It gets instead `{0}`")] diff --git a/crates/lib/src/relation.rs b/crates/lib/src/relation.rs index 1193a638791..3cb864fa2a6 100644 --- a/crates/lib/src/relation.rs +++ b/crates/lib/src/relation.rs @@ -416,21 +416,21 @@ impl<'a> RelValueRef<'a> { Self { data } } - pub fn get(&self, col: &'a FieldExpr, header: &'a Header) -> &'a AlgebraicValue { - match col { + pub fn get(&self, col: &'a FieldExpr, header: &'a Header) -> Result<&'a AlgebraicValue, RelationError> { + let val = match col { FieldExpr::Name(col) => { - if let Some(pos) = header.column_pos(col) { - if let Some(v) = self.data.elements.get(pos) { - v - } else { - unreachable!("Field `{col}` at pos {pos} not found on row: {:?}", self.data.elements) - } - } else { - unreachable!("Field `{col}` not found on `{}`. Fields:{}", header.table_name, header) - } + let pos = header + .column_pos(col) + .ok_or_else(|| RelationError::FieldNotFound(header.clone(), col.clone()))?; + self.data + .elements + .get(pos) + .ok_or_else(|| RelationError::FieldNotFoundAtPos(pos, col.clone()))? } FieldExpr::Value(x) => x, - } + }; + + Ok(val) } pub fn project(&self, cols: &[FieldExpr], header: &'a Header) -> Result { diff --git a/crates/vm/src/eval.rs b/crates/vm/src/eval.rs index 6f9075a683d..c9dc2242b68 100644 --- a/crates/vm/src/eval.rs +++ b/crates/vm/src/eval.rs @@ -458,16 +458,16 @@ pub fn build_query(mut result: Box, query: Vec) -> Result Result { match value { - ColumnOp::Field(field) => Ok(row.get(field, header).clone()), + ColumnOp::Field(field) => Ok(row.get(field, header)?.clone()), ColumnOp::Cmp { op, lhs, rhs } => Ok(self.compare_bin_op(row, *op, lhs, rhs, header)?.into()), } } @@ -108,7 +108,7 @@ impl ColumnOp { fn reduce_bool(&self, row: RelValueRef, value: &ColumnOp, header: &Header) -> Result { match value { ColumnOp::Field(field) => { - let field = row.get(field, header); + let field = row.get(field, header)?; match field.as_bool() { Some(b) => Ok(*b), @@ -156,7 +156,7 @@ impl ColumnOp { pub fn compare(&self, row: RelValueRef, header: &Header) -> Result { match self { ColumnOp::Field(field) => { - let lhs = row.get(field, header); + let lhs = row.get(field, header)?; Ok(*lhs.as_bool().unwrap()) } ColumnOp::Cmp { op, lhs, rhs } => self.compare_bin_op(row, *op, lhs, rhs, header),