diff --git a/query-algebrizer/src/clauses/mod.rs b/query-algebrizer/src/clauses/mod.rs index bfa04102..1f17d73f 100644 --- a/query-algebrizer/src/clauses/mod.rs +++ b/query-algebrizer/src/clauses/mod.rs @@ -599,12 +599,26 @@ impl ConjoiningClauses { .ok() } + fn get_attribute_for_value<'s>(&self, schema: &'s Schema, value: &TypedValue) -> Option<&'s Attribute> { + match value { + &TypedValue::Ref(id) => schema.attribute_for_entid(id), + &TypedValue::Keyword(ref kw) => schema.attribute_for_ident(kw), + _ => None, + } + } + fn get_attribute<'s, 'a>(&self, schema: &'s Schema, pattern: &'a Pattern) -> Option<&'s Attribute> { match pattern.attribute { PatternNonValuePlace::Entid(id) => schema.attribute_for_entid(id), PatternNonValuePlace::Ident(ref kw) => schema.attribute_for_ident(kw), + PatternNonValuePlace::Variable(ref var) => + // If the pattern has a variable, we've already determined that the binding -- if + // any -- is acceptable and yields a table. Here, simply look to see if it names + // an attribute so we can find out the type. + self.value_bindings.get(var) + .and_then(|val| self.get_attribute_for_value(schema, val)), _ => None, } diff --git a/query-algebrizer/src/clauses/pattern.rs b/query-algebrizer/src/clauses/pattern.rs index 6b4f8455..efce9982 100644 --- a/query-algebrizer/src/clauses/pattern.rs +++ b/query-algebrizer/src/clauses/pattern.rs @@ -460,8 +460,12 @@ mod testing { assert!(!cc.is_known_empty); assert_eq!(cc.from, vec![SourceAlias(DatomsTable::Datoms, "datoms00".to_string())]); - // ?x must be a ref. - assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref); + // ?x must be a ref, and ?v a boolean. + assert_eq!(cc.known_type(&x), Some(ValueType::Ref)); + + // We don't need to extract a type for ?v, because the attribute is known. + assert!(!cc.extracted_types.contains_key(&v)); + assert_eq!(cc.known_type(&v), Some(ValueType::Boolean)); // ?x is bound to datoms0.e. assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]);